Опции GCC для строжайшего кода C?

Какие параметры GCC должны быть установлены, чтобы GCC был максимально строгим? (и я имею в виду как можно более строгий) Я пишу на C89 и хочу, чтобы мой код был совместим с ANSI / ISO.


person Community    schedule 20.01.2012    source источник
comment
Строго говоря, вы должны четко указать, на какой стандарт вы ориентируетесь. ANSI X3.159-1989 и / или ISO / IEC 9899: 1990, ISO / IEC 9899: 1999 или C1X от рабочей группы ISO / IEC (open-std.org/JTC1/SC22/WG14) (JTC1 / SC22 / WG14). ANSI C и ISO C90 отличаются только нумерацией разделов самого стандарта AFAIK.   -  person mctylr    schedule 21.01.2012
comment
@mctylr: Я пишу на C89, кажется совершенно ясным.   -  person Keith Thompson    schedule 21.01.2012
comment
Строго говоря, C89 не соответствует требованиям ANSI / ISO. Текущий стандарт ISO C опубликован в 2011 году; это также текущий стандарт ANSI C; стандарты 1989, 1990 и 1999 официально устарели. Но это просто спор по поводу формулировки; по-прежнему широко распространена поддержка C89 / C90 (больше, чем для C99), и вы все еще можете соответствовать ей, даже если это больше не официальный стандарт.   -  person Keith Thompson    schedule 21.01.2012
comment
@KeithThompson Я не был уверен, есть ли неявная последняя как в ... хочу, чтобы мой код был последней стандартной жалобой ANSI / ISO.   -  person mctylr    schedule 26.01.2012


Ответы (2)


Я бы рекомендовал использовать:

-Wall -Wextra -std=c89 -pedantic -Wmissing-prototypes -Wstrict-prototypes \
    -Wold-style-definition

Вы должны компилировать как -O, так и -g, поскольку некоторые предупреждения доступны только при использовании оптимизатора (на самом деле, я обычно использую -O3 для обнаружения проблем). Вы можете предпочесть -std=gnu89, поскольку это отключает меньшее количество расширений в библиотеках. OTOH, если вы кодируете строгий ANSI C89, возможно, вы хотите их отключить. Параметр -ansi эквивалентен параметру -std=c89, но не настолько явным или гибким.

Отсутствующие прототипы предупреждают о функциях, которые используются (или определены внешние функции) без прототипа в области видимости. Строгие прототипы означают, что вы не можете использовать «пустые круглые скобки» для объявлений или определений функций (или указателей на функции); вам либо нужен (void), либо правильный список аргументов. В определении старого стиля упоминаются определения функций в стиле K&R, такие как:

int old_style(a, b) int a; double b; { ... }

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

См. Также: Какая лучшая команда- инструмент линии для очистки кода

person Jonathan Leffler    schedule 20.01.2012
comment
Опции -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition - хорошая идея, но они не касаются соответствия стандартам. Объявления и определения функций в старом стиле устарели с 1989 года, но они все еще являются частью языка; даже компиляторы, соответствующие требованиям C2011, должны их поддерживать. - person Keith Thompson; 21.01.2012
comment
@Keith: у вас включен флаг -pedantic при чтении: D Да, но я все же рекомендую использовать параметры, чтобы код был максимально переносимым для более поздних версий стандарта. Я не удивлюсь, если обнаружу, что C2021 наконец теряет стандартную поддержку для функций, не являющихся прототипами, хотя реализации, вероятно, продолжат поддерживать старые обозначения еще 10-20 лет после этого. C11 также исключает gets(); Я тоже не думаю, что он надолго исчезнет из библиотек. Этого следует избегать, даже если он полностью совместим с C89. - person Jonathan Leffler; 21.01.2012
comment
Я написал об этом сообщение: shitalshah. ru / p / - person Shital Shah; 12.07.2017
comment
@ShitalShah: Интересно. Ваш блог посвящен C ++, а не C, но это нормально. Я озадачен сообщением «ISO C99 требует использования остальных аргументов» (особенно при компиляции C ++). Я не понимаю, что это значит. Это связано с макросом __VA_ARGS__ - его надо где-то использовать? Или что-то еще. Я просмотрел отчет об ошибке и, честно говоря, не знал, какие изменения требовались. - person Jonathan Leffler; 12.07.2017

Этот набор опций неплохой:

-Wall -Wextra -ansi -pedantic

Вам нужно будет прочитать документацию, чтобы увидеть, не пропадают ли какие-либо лишние предупреждения из-за этой комбинации.

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

person Carl Norum    schedule 20.01.2012
comment
В документации сказано, что -ansi -pedantic должен обеспечить вам строгий ISO C90 и предупредит о ЛЮБОМ расширении GNU C (а не только о несовместимых). Вы можете использовать -pedantic-errors, если вам нужны ошибки. Хотя это не совсем вопрос строгости, вы можете рассмотреть вариант -Werror, который превратит предупреждения в ошибки. Хотя с философской точки зрения предупреждения не являются ошибками - person Jon L; 20.01.2012