Spec-Zone.ru › GCC 5

13.8 Некоторые изменения, которых мы не хотим вносить

В этом разделе перечислены изменения, которые часто запрашивают пользователи, но которые мы не вносим, потому что считаем, что GCC лучше без них.

  • Проверка количества и типов аргументов функции со старым определением и без прототипа.

    Такая функция будет работать только в отдельных случаях — только для вызовов, которые появляются в том же файле, что и вызываемая функция, после определения. Единственный способ надежно проверить все вызовы — добавить прототип для функции. Но добавление прототипа лишает мотивации к этой функции. Поэтому данная функция не стоит усилий.

  • Предупреждение об использовании выражения со знаком как сдвига.

    Операнды сдвига, скорее всего, являются со знаком чаще, чем без знака. Предупреждение об этом вызовет гораздо больше раздражения, чем пользы.

  • Предупреждение об присваивании значения со знаком беззнаковой переменной.

    Такие присваивания должны быть очень распространены; предупреждение об них вызовет больше раздражения, чем пользы.

  • Предупреждение, когда значение функции, отличное от void, игнорируется.

    C содержит много стандартных функций, возвращающих значение, которое большинство программ предпочитают игнорировать. Один очевидный пример — printf. Предупреждение об этой практике лишь заставляет защищенного программиста засорять программы десятками преобразований к void. Такие преобразования требуются так часто, что они становятся визуальным шумом. Написание этих преобразований становится настолько автоматическим, что они больше не передают полезной информации о намерениях программиста. Для функций, где значение возврата никогда не должно игнорироваться, используйте атрибут функции warn_unused_result (см. Атрибуты функций).

  • Установка -fshort-enums по умолчанию.

    Это приведет к несовместимости структуры хранения с большинством других компиляторов C. И это не кажется очень важным, учитывая, что тот же результат можно получить другими способами. Самый важный случай — когда перечисление находится внутри структуры, и в этом случае вы можете явно указать ширину поля.

  • Установка по умолчанию беззнакового типа для битовых полей на конкретных машинах, где «стандарт ABI» требует этого.

    Стандарт ISO C оставляет решение о том, будет ли битовое поле, объявленное как простое int, со знаком или без знака, за реализацией. Это фактически создаёт два альтернативных диалекта языка C.

    Компилятор GNU C поддерживает оба диалекта; вы можете указать диалект со знаком с помощью -fsigned-bitfields, а диалект без знака с помощью -funsigned-bitfields. Однако это оставляет открытым вопрос о том, какой диалект использовать по умолчанию.

    В настоящее время предпочтительный диалект делает простые битовые поля со знаком, потому что это проще. Поскольку int эквивалентно signed int в любом другом контексте, лучше всего, чтобы они были одинаковыми и в битовых полях.

    Некоторые производители компьютеров опубликовали стандарты интерфейса двоичного кода (ABI), в которых указано, что простые битовые поля должны быть беззнаковыми. Однако ошибочно делать какие-либо заявления об этом вопросе в ABI. Это связано с тем, что обработка простых битовых полей различает два диалекта языка C. Оба диалекта имеют смысл на любом типе машины. Факт, был ли конкретный объектный файл скомпилирован с битовыми полями со знаком или без знака, не имеет значения для других объектных файлов, даже если они обращаются к тем же битовым полям в тех же структурах данных.

    Любая данная программа написана на одном или другом из этих двух диалектов. Программа имеет шанс работать на большинстве машин, если она скомпилирована с соответствующим диалектом. Вряд ли она будет работать вообще, если скомпилирована с неправильным диалектом.

    Многие пользователи ценят компилятор GNU C, потому что он обеспечивает однородную среду на разных машинах. Эти пользователи испытывали бы неудобства, если бы компилятор по-разному обрабатывал простые битовые поля на определённых машинах.

    Иногда пользователи пишут программы, предназначенные только для конкретного типа машины. В этих случаях пользователи получили бы выгоду, если бы компилятор GNU C поддерживал по умолчанию тот же диалект, что и другие компиляторы на этой машине. Но такие приложения редки. А пользователи, пишущие программу для работы на нескольких типах машин, не могут получить выгоду от такого рода совместимости.

    Вот почему GCC будет и дальше обрабатывать простые битовые поля одинаково на всех типах машин (по умолчанию).

    Есть некоторые аргументы в пользу того, чтобы по умолчанию использовать беззнаковые битовые поля на всех машинах. Если, например, это станет универсальным де-факто стандартом, будет разумно, если GCC примет его. Это следует учитывать в будущем.

    (Конечно, пользователи, сильно озабоченные переносимостью, должны явно указывать в каждом битовом поле, со знаком оно или без знака. Таким образом, они пишут программы, которые имеют одинаковый смысл в обоих диалектах C.)

  • Отмена определения __STDC__ при отсутствии -ansi.

    В настоящее время GCC определяет __STDC__ безусловно. Это обеспечивает хорошие результаты на практике.

    Программисты обычно используют условные операторы на __STDC__, чтобы спросить, безопасно ли использовать определённые функции ISO C, такие как прототипы функций или конкатенация токенов ISO. Поскольку стандартный gcc поддерживает все функции ISO C, правильный ответ на эти вопросы — «да».

    Некоторые пользователи пытаются использовать __STDC__ для проверки наличия определённых функций библиотеки. Это фактически неправильное использование в программе ISO C, потому что стандарт ISO C гласит, что соответствующая реализация автономной среды должна определять __STDC__, даже если у неё нет функций библиотеки. ‘gcc -ansi -pedantic’ — это соответствующая реализация автономной среды, и поэтому она обязана определить __STDC__, даже если она не поставляется с библиотекой ISO C.

    Иногда люди утверждают, что определение __STDC__ в компиляторе, не полностью соответствующем стандарту ISO C, каким-то образом нарушает стандарт. Это нелогично. Стандарт — это стандарт для компиляторов, которые заявляют о поддержке ISO C, например, ‘gcc -ansi’ — а не для других компиляторов, например, стандартного gcc. Любые заявления стандарта ISO C применимы к проектированию стандартного gcc без -ansi только по практическим соображениям, а не как требование.

    GCC обычно определяет __STDC__ как 1 и, кроме того, определяет __STRICT_ANSI__, если вы указали опцию -ansi или опцию -std для строгого соответствия какой-либо версии ISO C. На некоторых хостах системные заголовочные файлы используют другую конвенцию, где __STDC__ обычно равен 0, но равен 1, если пользователь указывает строгое соответствие стандарту C. GCC следует конвенции хоста при обработке системных заголовочных файлов, но при обработке пользовательских файлов следует обычной конвенции GNU C.

  • Отмена определения __STDC__ в C++.

    Программы, написанные для компиляции с помощью трансляторов C++ в C, получают значение __STDC__ от компилятора C, который используется позже. Эти программы должны проверять __STDC__ для определения типа препроцессора C, который использует компилятор: должны ли они конкатенировать токены по стандарту ISO C или по традиционному методу.

    Эти программы правильно работают с GNU C++ при определении __STDC__. В противном случае они не будут работать.

    Кроме того, многие заголовочные файлы написаны для предоставления прототипов в ISO C, но не в традиционном C. Многие из этих заголовочных файлов могут работать без изменений в C++ при условии определения __STDC__. Если __STDC__ не определён, все они потерпят неудачу, и все они должны быть изменены для явной проверки на C++.

  • Удаление «пустых» циклов.

    Исторически GCC не удалял «пустые» циклы, исходя из предположения, что наиболее вероятная причина их вставки в программу — это задержка, поэтому удаление их не ускорит выполнение реальных программ.

    Однако, обоснование состоит в том, что оптимизация непустого цикла не может привести к пустому. Это было верно для тщательно написанных программ C, скомпилированных с менее мощными оптимизаторами, но не всегда так для тщательно написанных программ C++ или с более мощными оптимизаторами. Таким образом, GCC будет удалять операции из циклов, когда сможет определить, что эти операции не видны внешним образом (кроме, конечно, времени, затраченного на их выполнение). В случае, если цикл можно доказать конечным, GCC также удалит сам цикл.

    Обратите внимание на это при выполнении тестов времени выполнения, например, следующий цикл может быть полностью удален, при условии, что some_expression доказуемо не изменяет глобальное состояние.

    {
       int sum = 0;
       int ix;
    
       for (ix = 0; ix != 10000; ix++)
          sum += some_expression;
    }

    Даже если sum накапливается в цикле, эта сумма не используется, поэтому накопление может быть удалено.

  • Выполнение побочных эффектов в том же порядке, что и в другом компиляторе.

    Никогда безопасно полагаться на порядок вычисления побочных эффектов. Например, вызов функции, подобный этому, может вести себя совершенно по-разному в разных компиляторах:

    void func (int, int);
    
    int i = 2;
    func (i++, i++);

    Не гарантируется (ни в стандарте языка C, ни в стандарте языка C++), что инкременты будут вычислены в определённом порядке. Любой инкремент может произойти первым. func может получить аргументы ‘2, 3’, или ‘3, 2’, или даже ‘2, 2’.

  • Преобразование некоторых предупреждений в ошибки по умолчанию.

    Некоторые наборы тестов ISO C сообщают об ошибке, когда компилятор не выдаёт сообщение об ошибке для определённой программы.

    Стандарт ISO C требует сообщения «диагностики» для определённых видов некорректных программ, но GCC определяет предупреждение как сообщение диагностики. Если GCC выдаёт предупреждение, но не ошибку, это правильная поддержка ISO C. Если наборы тестов называют это «ошибкой», они должны быть запущены с опцией GCC -pedantic-errors, которая преобразует эти предупреждения в ошибки.

Далее: Предупреждения и ошибки, Предыдущее: Непонимание C++, Наверх: Проблемы [Содержание][Индекс]

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-5.5.0/gcc/Non-bugs.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API