15.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-15.3.0/gcc/Disappointments.html