Полезные флаги GCC для C
за задание -Wall, а параметр -std=XXX, что другие действительно полезные, но менее известные флаги компилятора для использования в C?
меня особенно интересуют любые дополнительные предупреждения и / или превращение предупреждений в ошибки в некоторых случаях, чтобы полностью свести к минимуму любые случайные несоответствия типов.
23 ответов:
несколько
-fопции генерации кода интересны:
The
-ftrapvфункция приведет к прерыванию программы при переполнении целого числа со знаком (формально "неопределенное поведение" в C).
-fverbose-asmэто полезно, если вы компилируете с-Sчтобы изучить вывод сборки-он добавляет некоторые информативные комментарии.
-finstrument-functionsдобавляет код для вызова пользовательских функций профилирования в каждой функции точка входа и выхода.
вот мои:
-Wextra,-Wall: эфирное.-Wfloat-equal: полезно, потому что обычно тестирование чисел с плавающей точкой на равенство-это плохо.-Wundef: предупреждает, если неинициализированный идентификатор оценивается в случае*.-Wswitch-enum: предупредить всякий раз, когдаswitchоператор имеет индекс перечисляемого типа и не имеетcaseдля одного или нескольких именованных кодов этого перечисления*.-Wconversion: предупреждение для неявных преобразований, которые могут изменить значение*.-Wunreachable-code: предупредите, если компилятор обнаружит, что код никогда не будет выполнен*.те, что помечены * иногда дают слишком много ложных предупреждений, поэтому я использую их по мере необходимости.
всегда использовать
-Oили выше (-O1,-O2,-Osи т. д.). На уровне оптимизации по умолчанию gcc идет на скорость компиляции и не делает достаточного анализа, чтобы предупредить о таких вещах, как unitialized variables.подумайте о создании
-Werrorполитика, поскольку предупреждения, которые не останавливают компиляцию, как правило, игнорируются.
-Wallв значительной степени включает предупреждения, которые, скорее всего, будут ошибками.предупреждения включенными в
-Wextraкак правило, флаг общий, законный код. Они могут быть полезны для обзоров кода (хотя программы в стиле lint находят гораздо больше подводных камней более гибкими), но я бы не включал их для нормальной разработки.
-Wfloat-equal- хорошая идея, если разработчики проекта не знакомы с плавающей точкой, и плохая идея, если они есть.
-Winit-selfполезно; интересно, почему он не включен в-Wuninitialized.
-Wpointer-arithэто полезно, если у вас в основном-портативный код, который не работает с-pedantic.
-save-tempsЭто оставляет позади результаты препроцессора и сборки.
предварительно обработанный источник полезен для отладки макросов.
сборка полезна для определения того, какие оптимизации вступили в силу. Например, вы можете проверить, что GCC выполняет оптимизацию хвостового вызова для некоторых рекурсивных функций, так как без него вы можете потенциально переполнить стек.
Я удивлен, что никто еще этого не сказал - самый полезный флаг, насколько мне известно, это
-gкоторый помещает отладочную информацию в исполняемый файл таким образом, что вы можете отлаживать его и проходить через Источник (Если вы не владеете и не читаете сборку и не любитеstepiкоманда) программы во время ее выполнения.
-fmudflap -- добавляет проверки времени выполнения для всех рискованных операций указателя, чтобы поймать UB. Это эффективно иммунизирует вашу программу снова переполнения буфера и помогает поймать все виды висячих указателей.
вот демо:
$ cat mf.c int main() { int a[10]; a[10]=1; // <-- o noes, line 4 } $ gcc -fmudflap mf.c -lmudflap $ ./a.out ******* mudflap violation 1 (check/write): time=1280862302.170759 ptr=0x7fff96eb3d00 size=44 pc=0x7f3a575503c1 location=`mf.c:4:2 (main)' /usr/lib/libmudflap.so.0(__mf_check+0x41) [0x7f3a575503c1] ./a.out(main+0x90) [0x400a54] /lib/libc.so.6(__libc_start_main+0xfd) [0x7f3a571e2c4d] Nearby object 1: checked region begins 0B into and ends 4B after mudflap object 0xf9c560: name=`mf.c:3:6 (main) a' bounds=[0x7fff96eb3d00,0x7fff96eb3d27] size=40 area=stack check=0r/3w liveness=3 alloc time=1280862302.170749 pc=0x7f3a57550cb1 number of nearby objects: 1
не связанные с C/C++, но полезно в любом случае :
@fileПоместите все вышеперечисленные хорошие флаги (которые вы все указали) в "файл" и используйте этот флаг Выше, чтобы использовать все флаги в этом файле вместе.
например:
File : compilerFlags
стена
- std=c99
-Wextra
затем скомпилировать :
gcc yourSourceFile @compilerFlags
это не очень полезно для выявления ошибок, но редко упоминается с помощью
-Sчтобы проверить вывод сборки намного, намного приятнее.синтаксис сборки AT&T слишком сильно болит у меня в голове.
мой makefile обычно содержит
CFLAGS= -Wall -Wextra -Weffc++ -Os -ggdb ... g++ $(CFLAGS) -o junk $< gcc $(CFLAGS) -o $@ $< rm -f junkнаиболее важные из этих вариантов были обсуждены ранее, поэтому я укажу на две функции, которые еще не были указаны:
хотя я работаю над кодовой базой, что должен чтобы быть простым C для переносимости на какую-то платформу, которая еще не имеет достойного компилятора C++, я делаю "дополнительную" компиляцию с компилятором C++ (в дополнение к компилятору C). Что имеет 3 преимущества:
- компилятор C++ иногда дает мне лучшие предупреждающие сообщения, чем компилятор C.
- компилятор C++ принимает параметр-Weffc++, который иногда дает мне некоторые полезные советы, которые я пропустил бы, если бы я только скомпилировал его в простом C.
- я могу относительно легко переносить код на C++, избегая нескольких граничных условий, когда простой код C является недопустимым кодом C++ (например, определение переменной с именем "тип bool.)"
Да, я безнадежно оптимистичная Поллианна, которая продолжает думать, что конечно в любой месяц теперь, когда одна платформа будет объявлена устаревшей, или получить достойный компилятор C++, и мы можем, наконец, перейти на C++. На мой взгляд, это неизбежно - вопрос только в том, произойдет ли это до или после того, как руководство наконец выдаст каждому пони. : -)
вот большой флаг, который не был упомянут:
-Werror-implicit-function-declarationвыдавать ошибку всякий раз, когда функция используется перед объявлением.
man gccруководство полно интересных флагов с хорошими описаниями. Тем не менее, - Wall, вероятно, сделает gcc как можно более подробным. Если вам нужны более интересные данные, вы должны взглянуть на valgrind или какой-либо другой инструмент для проверки ошибок.
Ну
-Wextraдолжно быть нормой.-Werrorпревращает предупреждения в ошибки (которые могут быть очень раздражает, особенно если вы компилируете без-Wno-unused-result).-pedanticв сочетании сstd=c89дает вам дополнительные предупреждения, если вы используете стандарте C99 функции.но это все. Вы не можете настроить компилятор C на что-то большее, чем сохранение типа, чем сам C.
здесь
-Werror, который рассматривает все предупреждения как ошибки и останавливает компиляцию. Элементgccстраница руководства объясняет каждый переключатель командной строки для вашего компилятора.
-M*семейные варианты.Они позволяют писать файлы make, которые автоматически определяют, от каких заголовочных файлов должны зависеть исходные файлы c или c++. GCC создаст файлы make с этой информацией о зависимостях, а затем вы-включите их из своего основного файла make.
вот пример чрезвычайно общего файла makefile с использованием -MD и-MP, который скомпилирует каталог, полный исходных файлов c++ и заголовочных файлов, и выяснит все зависимости автоматически:
CPPFLAGS += -MD -MP SRC = $(wildcard *.cpp) my_executable: $(SRC:%.cpp=%.o) g++ $(LDFLAGS) -o $@ $^ -include $(SRC:%.cpp=%.d)вот сообщение в блоге, которое обсуждает его более подробно: http://www.microhowto.info/howto/automatically_generate_makefile_dependencies.html
-Wfloat-equalот:http://mces.blogspot.com/2005/07/char-const-argv.html
одно из других новых предупреждений, которые мне нравятся,- wfloat-equal. Это предупреждает, когда у вас [есть] число с плавающей запятой в условии равенства. Это же брильянт! Если у вас есть каждый запрограммированный алгоритм компьютерной графики или (хуже:) вычислительной геометрии, вы знаете, что никакие два поплавка никогда не совпадают с равенством...
я нашел эту тему, ища флаг, чтобы исправить конкретную проблему, я не вижу его здесь, поэтому я добавлю тот, который просто ставил меня в тупик мой пост:
The
-Wformat=2флаг
-Wformat=> проверить звонкиprintfиscanfи т. д., чтобы убедиться, что предоставленные аргументы имеют типы, соответствующие указанной строке формата...и очень важная часть об этом (согласно GCC руководство):
-Wformatвходит в-Wall. Для большего контроля над некоторыми аспектами проверки формата, параметры-Wformat-y2k,-Wno-format-extra-args,-Wno-format-zero-length,-Wformat-nonliteral,-Wformat-securityи-Wformat=2доступны, но не включены в стену.-Итак, только потому, что у вас есть
-Wallне значит, что у вас есть все это. ;)
Я иногда использую
-sдля гораздо меньшего исполняемого файла:-s Remove all symbol table and relocation information from the executable.Источник:http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options
хотя этот ответ может быть немного не по теме и вопрос достойный +1 от меня, так как
меня особенно интересуют любые дополнительные предупреждения и / или превращение предупреждений в ошибки в некоторых случаях, чтобы полностью свести к минимуму любые случайные несоответствия типов.есть инструмент, который должен поймать все ошибки и потенциальные ошибки, которые могут быть не очевидны, есть шина который IMHO делает способ лучше работать в ловле ошибок по сравнению для gcc или любого другого компилятора, если на то пошло. Это достойный инструмент, чтобы иметь в вашем сундуке с инструментами.статическая проверка с помощью инструмента типа lint, такого как шина, должна была быть частью инструментальной цепочки компилятора.
меня особенно интересуют любые дополнительные предупреждения,
кроме
-Wallна-Wили (-Wработает со старыми версиями gcc, а также более новыми; более поздние версии поддерживают альтернативное имя-Wextra, что означает то же самое, но более описательно) включает различные дополнительные предупреждения.есть также еще больше предупреждений, которые не включены ни одним из них, как правило, для вещей это более сомнительно плохо. Набор доступных опций зависит от того, какую версию gcc вы используете-consult
man gccилиinfo gccдля деталей, или см. документации для конкретной версии gcc, которая вас интересует. И-pedanticвыдает все предупреждения, необходимые для конкретного используемого стандарта (который зависит от других параметров, таких как-std=xxxили-ansi) и жалуется на использование расширений gcc.и/или поворота предупреждения в ошибки в некоторых случаях, чтобы абсолютно свести к минимуму любой случайный тип несоответствия.
-Werrorпревращает все предупреждения как ошибки. Я не думаю, что gcc позволяет вам делать это выборочно для конкретных предупреждений.вы, вероятно, обнаружите, что вы должны быть избирательны о том, какие предупреждения включены на основе каждого проекта (особенно если вы используете
-Werror), так как заголовочные файлы из внешних библиотек могут задействовать некоторые из них. (-pedanticв частности, как правило чтобы быть бесполезным в этом отношении, по моему опыту.)
-Wmissing-prototypes: если глобальная функция определена без предыдущего объявления прототипа.-Wformat-security: предупреждает об использовании функций форматирования, представляющих возможные проблемы безопасности. В настоящее время это предупреждает о вызовахprintfиscanfфункции, где строка формата не является строковым литералом и нет аргументов формата
Comments