13.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, но не используйте битовые поля.
- GCC поставляется с скриптами оболочки для исправления некоторых известных проблем в системных заголовочных файлах. Они устанавливают исправленные копии различных заголовочных файлов в специальный каталог, где GCC обычно будет их искать. Скрипты адаптируются к различным системам, проверяя все системные заголовочные файлы на известные проблемные случаи.
Если установлены новые системные заголовочные файлы, ничего автоматически не организует обновление исправленных заголовочных файлов. Их можно обновить, используя скрипт
mkheaders, установленный в libexecdir/gcc/target/version/install-tools/. - На системах 68000 и x86, например, можно получить парадоксальные результаты, если проверить точные значения чисел с плавающей точкой. Например, можно обнаружить, что число с плавающей точкой, которое не является NaN, не равно самому себе. Это происходит из-за того, что регистры с плавающей точкой хранят несколько больше битов точности, чем помещается в
doubleв памяти. Компилируемый код перемещает значения между памятью и регистрами с плавающей точкой по своему усмотрению, а при перемещении в память их обрезает.Эту проблему можно частично избежать, используя опцию -ffloat-store (см. Параметры оптимизации).
- На AIX и других платформах без поддержки слабых символов шаблоны необходимо явно экземпляризировать, а символы статических членов шаблонов не будут сгенерированы.
- На AIX GCC сканирует объектные файлы и библиотечные архивы для статических конструкторов и деструкторов при линковке приложения до того, как линкер обрезает неиспользуемые символы. Это необходимо для предотвращения ошибочного предположения линковщика AIX о том, что статический конструктор или деструктор не используются, и их удаления до сканирования. Все найденные статические конструкторы и деструкторы будут обработаны, даже если модули, в которых они встречаются, не используются программой. Это может привести как к увеличению размера исполняемого файла, так и к неожиданным ссылкам на символы.
Далее: Недоразумения C++, Предыдущее: Стандартные библиотеки, Вверх: Проблемы [Содержание][Индекс]
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-6.5.0/gcc/Disappointments.html