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 C только для того, чтобы избежать ошибки для показанного выше примера. - Доступ к полям бит, даже в переменных 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-10.5.0/gcc/Disappointments.html