14.6 Разочарования и недоразумения ¶
Эти проблемы, возможно, прискорбны, но мы не знаем никакого практического способа их обойти.
- Некоторые локальные переменные не распознаются отладчиками при компиляции с оптимизацией.
Это происходит потому, что иногда GCC оптимизирует переменную до полного исключения. Нет способа указать отладчику, как вычислить значение, которое «была бы» такая переменная, и неясно, что это вообще желательно. Поэтому GCC просто не упоминает исключённую переменную при записи отладочной информации.
При использовании оптимизации следует ожидать некоторой степени расхождения между исполняемым файлом и исходным кодом.
- Пользователи часто считают ошибкой, когда GCC сообщает об ошибке для кода подобного этому:
int foo (struct mumble *); struct mumble { … }; int foo (struct mumble *x) { … }Этот код действительно ошибочен, так как область действия
struct mumbleв прототипе ограничена списком аргументов, содержащим его. Он не относится кstruct mumble, определённой в области файла непосредственно ниже — это два не связанных типа с похожими именами в разных областях действия.Однако в определении
foo, используется тип области файла, так как он доступен для наследования. Таким образом, определение и прототип не совпадают, и вы получаете ошибку.Это поведение может показаться глупым, но именно это указано в стандарте ISO. Вы легко можете заставить свой код работать, поместив определение
struct mumbleвыше прототипа. Не стоит вносить несовместимость со стандартом ISO, чтобы избежать ошибки в приведённом выше примере. - Доступ к полям битов, даже в переменных volatile, осуществляется путём доступа к более крупным объектам, таким как байт или слово. Нельзя полагаться на размер объекта, который используется для чтения или записи поля битов; он может даже изменяться для данного поля битов в зависимости от конкретного использования.
Если вам нужно контролировать количество памяти, к которой осуществляется доступ, используйте volatile, но не используйте поля битов.
- GCC поставляется со скриптами оболочки для исправления определённых известных проблем в системных заголовочных файлах. Они устанавливают исправленные копии различных заголовочных файлов в специальный каталог, где GCC обычно их и будет искать. Скрипты адаптируются к различным системам, просматривая все системные заголовочные файлы в поисках известных проблемных случаев.
Если установлены новые системные заголовочные файлы, ничего автоматически не обновляет исправленные заголовочные файлы. Их можно обновить, используя скрипт
mkheaders, установленный в libexecdir/gcc/target/version/install-tools/. - Например, на системах 68000 и x86 вы можете получить парадоксальные результаты, если будете тестировать точные значения чисел с плавающей точкой. Например, вы можете обнаружить, что число с плавающей точкой, которое не является NaN, не равно самому себе. Это происходит потому, что регистры с плавающей точкой хранят несколько дополнительных битов точности, чем помещается в
doubleв памяти. Компилируемый код перемещает значения между памятью и регистрами с плавающей точкой по своему усмотрению, и при перемещении их в память они усекаются.Вы можете частично избежать этой проблемы, используя опцию -ffloat-store (см. Параметры, управляющие оптимизацией).
- На AIX и других платформах без поддержки слабых символов шаблоны должны быть явным образом инстанцированы, а символы для статических членов шаблонов не будут генерированы.
- На AIX GCC сканирует объектные файлы и библиотечные архивы в поисках статических конструкторов и деструкторов при линковке приложения до того, как линкер удалит неиспользуемые символы. Это необходимо для предотвращения случайного предположения линком AIX о том, что статический конструктор или деструктор не используются и удаления их до момента сканирования. Все найденные статические конструкторы и деструкторы будут использоваться, даже если модули, в которых они находятся, не используются программой. Это может привести к увеличению размера исполняемого файла и неожиданным ссылкам на символы.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-11.4.0/gcc/Disappointments.html