Полезные флаги GCC для C



за задание -Wall, а параметр -std=XXX, что другие действительно полезные, но менее известные флаги компилятора для использования в C?



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

978   23  

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

-march=native чтобы создать оптимизированный код для платформы (=чип), на которой вы компилируете

Если вам нужно знать флаги препроцессора, которые предопределены компилятором:

echo | gcc -E -dM -

это не очень полезно для выявления ошибок, но редко упоминается с помощью -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 преимущества:

  1. компилятор C++ иногда дает мне лучшие предупреждающие сообщения, чем компилятор C.
  2. компилятор C++ принимает параметр-Weffc++, который иногда дает мне некоторые полезные советы, которые я пропустил бы, если бы я только скомпилировал его в простом C.
  3. я могу относительно легко переносить код на C++, избегая нескольких граничных условий, когда простой код C является недопустимым кодом C++ (например, определение переменной с именем "тип bool.)"

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

-Wstrict-prototypes -Wmissing-prototypes

вот большой флаг, который не был упомянут:

-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

    Ничего не найдено.