Какова цель использования -патентной в компиляторе GCC/g++?

В этой заметке говорится:

-ansi: сообщает компилятору о реализации опции языка ANSI. Это превращается отключить определенные "функции" GCC, которые несовместимы с ANSI стандарт.

-pedantic: используется вместе с -ansi, это говорит, что компилятор строго придерживается стандарта ANSI, отказ от любого кода, который не является совместимый.

Прежде всего:

  • Какова цель опций -pedantic и -ansi компилятора GCC/g++ (я не мог понять вышеприведенное описание)?
  • Может ли кто-нибудь сказать мне правильные обстоятельства для использования этих двух вариантов?
  • Когда следует использовать их?
  • Они важны?

Ответ 1

Компиляторы GCC всегда пытаются скомпилировать вашу программу, если это вообще возможно. Однако в некоторых случаи, стандарты C и С++ указывают, что определенные расширения запрещены. Соответствующие компиляторы такие как gcc или g++, должны выдавать диагностику, когда эти расширения встречаются. Например, gcc-компиляторы -педантичный параметр заставляет gcc выдавать предупреждения в таких случаях. Использование более строгих Опция -pedantic-errors преобразует такие диагностические предупреждения в ошибки, которые вызовут компиляцию терпеть неудачу в таких точках. Только те не-ISO-конструкции, которые должны быть помечены соответствующим компилятор генерирует предупреждения или ошибки.

Ответ 2

Я использую его все время в своем кодировании.

Флаг -ansi эквивалентен -std=c89. Как уже отмечалось, он отключает некоторые расширения GCC. Добавление -pedantic отключает больше расширений и генерирует больше предупреждений. Например, если у вас есть строковый литерал длиной более 509 символов, тогда -pedantic предупреждает об этом, поскольку он превышает минимальный предел, требуемый стандартом C89. То есть, каждый компилятор C89 должен принимать строки длиной 509; им разрешено принимать дольше, но если вы педантичны, он не переносится для использования более длинных строк, даже если компилятору разрешено принимать более длинные строки и без педантичных предупреждений GCC также примет их.

Ответ 3

-ansi является устаревшим переключателем, который запрашивает компилятор в соответствии с 30-летней устаревшей версией стандарта C, ISO/IEC 9899: 1990, который по сути является ребрендингом стандарта ANSI X3.159-1989 "Программирование Язык C. Почему устарел? Потому что после того, как C90 был опубликован ISO, ISO отвечал за стандартизацию C, и все технические исправления к C90 были опубликованы ISO. Таким образом, более вероятно использовать -std=c90.

Без этого переключателя последние компиляторы C GCC будут соответствовать языку C, стандартизированному в ISO/IEC 9899: 2011.

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

Использование переключателя помогает гарантировать, что код должен компилироваться в этих устаревших компиляторах.


-pedantic интересный. В отсутствие -pedantic, даже когда запрашивается конкретный стандарт, GCC по-прежнему допускает некоторые расширения, которые не приемлемы в стандарте C. Рассмотрим для примера программу

struct test {
    int zero_size_array[0];
};

В пункте 6.7.6.2p1 проекта С11 n1570 говорится:

В дополнение к необязательным квалификаторам типов и ключевому слову static, [и] могут разделять выражение или *. Если они разграничивают выражение (которое определяет размер массива), выражение должно иметь целочисленный тип. Если выражение является константным выражением, оно должно иметь значение больше нуля. [...]

Стандарт C требует, чтобы длина массива была больше нуля; и этот пункт находится в ограничениях; Стандарт гласит следующее 5.1.1.3p1:

Соответствующая реализация должна генерировать по крайней мере одно диагностическое сообщение (идентифицированное определенным реализацией способом), если блок преобразования или блок предварительной обработки содержит нарушение какого-либо синтаксического правила или ограничения, даже если поведение также явно указано как неопределенное или как реализация. определены. Диагностические сообщения не должны создаваться при других обстоятельствах. 9)

Однако, если вы скомпилируете программу с помощью gcc -c -std=c90 pedantic_test.c, предупреждение не gcc -c -std=c90 pedantic_test.c.

-pedantic заставляет компилятор фактически соответствовать стандарту C; так что теперь он выдаст предупреждение, как того требует стандарт:

gcc -c -pedantic -std=c90 pedantic_test.c
pedantic_test.c:2:9: warning: ISO C forbids zero-size array ‘zero_size_array [-Wpedantic]
     int zero_size_array[0];
         ^~~~~~~~~~~~~~~

Таким образом, для максимальной переносимости недостаточно -pedantic вы должны также использовать -pedantic (или -pedantic-errors), чтобы убедиться, что GCC действительно соответствует букве стандарта.


Последняя часть вопроса -ansi использования -ansi с C++. ANSI никогда не стандартизировал язык C++ - только перенял его из ISO, так что это имеет такой же смысл, как сказать "английский язык стандартизирован Францией". Однако GCC все еще, кажется, принимает это для C++, как бы глупо это ни звучало.

Ответ 4

В принципе, ваш код будет намного проще компилироваться под другими компиляторами, которые также реализуют стандарт ANSI, и, если вы будете осторожны в том, какие библиотеки/приложения api вы используете, в других операционных системах/платформах.

Первый, отключает КОНКРЕТНЫЕ функции GCC. (-ansi) Второй, будет жаловаться на НИЧЕГО вообще, что не соответствует стандарту (не только специфические особенности GCC, но и ваши конструкции). (-pedantic).

Ответ 5

Если ваш код должен быть переносимым, вы можете проверить, что он компилируется без каких-либо расширений gcc или других нестандартных функций. Если ваш код компилируется с помощью -pedantic -ansi, то теоретически он должен скомпилировать ОК с любым другим стандартным компилятором ANSI.

Ответ 6

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

Ответ 7

Другие ответили достаточно. Я хотел бы добавить несколько примеров частых расширений:

Функция main возвращает void. Это не определено стандартом, то есть он будет работать только на некоторых компиляторах (включая GCC), но не на других. Кстати, int main() и int main(int, char**) - это две сигнатуры, которые стандарт определяет.

Другим популярным расширением является возможность объявлять и определять функции внутри других функций:

void f()
{
    void g()
    {
       // ...
    }

    // ...
    g();
    // ...
}

Это нестандартно. Если вы хотите такого поведения, посмотрите С++ 11 lambdas

Ответ 8

Pedantic делает это так, что компилятор gcc отклоняет все расширения GNU C, а не только те, которые делают его совместимым с ANSI.

Ответ 9

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

 ISO C forbids braced-groups within expressions