Помимо настройки -Wall
и настройки -std=XXX
, какие еще действительно полезные, но менее известные флаги компилятора существуют для использования в C?
Меня особенно интересуют любые дополнительные предупреждения и / или превращение предупреждений в ошибки в некоторых случаях, чтобы абсолютно минимизировать случайные несоответствия типов.
c
gcc
compiler-flags
Мэтт Джойнер
источник
источник
-save-temps
,-Wshadow
и-fmudflap
были величайшими находками, о которых я не знал, спасибо всем.gcc -c [flags-go-here] -o myprog.o myprog.c
для компиляции (а не ссылки) программы на Си.Ответы:
Несколько
-f
вариантов генерации кода интересны:-ftrapv
Функция заставит программу , чтобы прервать на подписанном целочисленное переполнение (формально «неопределенное поведение» в C).-fverbose-asm
полезно, если вы компилируете с помощью-S
для проверки вывода сборки - он добавляет некоторые информативные комментарии.-finstrument-functions
добавляет код для вызова пользовательских профилирующих функций в каждой точке входа и выхода функции.источник
-ftrapv
, посмотрите здесь stackoverflow.com/questions/20851061/… .. похоже, есть ошибка, долго ожидающая, чтобы быть исправленной.Вот мой:
-Wextra
,-Wall
: Важное значение.-Wfloat-equal
: полезно, потому что обычно проверка чисел с плавающей точкой на равенство плохая.-Wundef
: предупредить, если неинициализированный идентификатор оценивается в#if
директиве.-Wshadow
: предупреждает всякий раз, когда локальная переменная затеняет другую локальную переменную, параметр или глобальную переменную или когда затенена встроенная функция.-Wpointer-arith
: предупредить, если что-то зависит от размера функции илиvoid
.-Wcast-align
: предупреждает всякий раз, когда указатель приведен так, что требуемое выравнивание цели увеличивается. Например, предупредите, если achar *
приведен кint *
на машинах, где целые числа могут быть доступны только на двух- или четырехбайтовых границах.-Wstrict-prototypes
: предупредить, если функция объявлена или определена без указания типов аргументов.-Wstrict-overflow=5
: предупреждает о случаях, когда компилятор оптимизирует, исходя из предположения, что переполнение со знаком не происходит. (Значение 5 может быть слишком строгим, см. Страницу руководства.)-Wwrite-strings
: дать строковым константамconst char[
длину типа,]
чтобы при копировании адреса одного в неconst char *
указатель получало предупреждение.-Waggregate-return
: предупредить, если какие-либо функции, которые возвращают структуры или объединения, определены или вызваны.-Wcast-qual
: предупреждает всякий раз, когда указатель приведен для удаления спецификатора типа из целевого типа * .-Wswitch-default
: предупреждать, когда вswitch
выражении нетdefault
регистра * .-Wswitch-enum
: warn всякий раз, когда уswitch
оператора есть индекс перечислимого типа и отсутствуетcase
один или несколько именованных кодов этого перечисления * .-Wconversion
: предупреждение для неявных преобразований, которые могут изменить значение * .-Wunreachable-code
: предупредить, если компилятор обнаружит, что код никогда не будет выполнен * .Отмеченные * иногда дают слишком много ложных предупреждений, поэтому я использую их по мере необходимости.
источник
-Wformat=2
: Дополнительные проверки формата в функциях printf / scanf.-Wall
?-Wwrite-strings
потому что я ненавижу это так сильно.-Wwrite-strings
специально сказано, что оно не является частью-Wall
: gcc.gnu.org/onlinedocs/gcc/… . Может быть, что-то еще в вашей настройке устанавливает этот флаг? Или, может быть, вы компилируете C ++?Всегда используйте
-O
или выше (-O1
,-O2
,-Os
и т.д.). На уровне оптимизации по умолчанию gcc использует скорость компиляции и не проводит достаточного анализа, чтобы предупредить о таких вещах, как унифицированные переменные.Рассмотрите возможность разработки
-Werror
политики, поскольку предупреждения, которые не останавливают компиляцию, обычно игнорируются.-Wall
в значительной степени включает предупреждения, которые, скорее всего, будут ошибками.Предупреждения, включенные в,
-Wextra
имеют тенденцию помечать общий, законный код. Они могут быть полезны для рецензирования кода (хотя программы в стиле lint находят гораздо больше ловушек более гибкими), но я бы не стал их включать для нормальной разработки.-Wfloat-equal
хорошая идея, если разработчики проекта не знакомы с плавающей запятой, и плохая идея, если они есть.-Winit-self
является полезным; Интересно, почему это не входит в-Wuninitialized
.-Wpointer-arith
полезно, если у вас есть в основном переносимый код, с которым не работает-pedantic
.источник
Это оставляет позади результаты препроцессора и сборки.
Предварительно обработанный источник полезен для отладки макросов.
Сборка полезна для определения того, какие оптимизации вступили в силу. Например, вы можете захотеть убедиться, что GCC выполняет оптимизацию хвостового вызова для некоторых рекурсивных функций, поскольку без этого вы можете потенциально переполнить стек.
источник
Я удивлен, что никто еще не сказал это - самый полезный флаг, насколько мне известно, это то,
-g
что отладочная информация помещается в исполняемый файл, так что вы можете отлаживать ее и переходить к исходному коду (если вы не опытный и не читаете сборку и какstepi
команда) программы во время ее выполнения.источник
-fmudflap - добавляет проверки во время выполнения всех рискованных операций с указателями, чтобы поймать UB. Это эффективно предотвращает переполнение буфера в вашей программе и помогает отлавливать все виды висячих указателей.
Вот демо:
источник
-fmudflap
больше не поддерживается с GCC 4.9, вы получаетеwarning: switch '-fmudflap' is no longer supported
. Он был заменен AddressSanitizer.Не очень связано с C / C ++, но полезно в любом случае:
Поместите все вышеупомянутые хорошие флаги (которые вы все указали) в «файл» и используйте этот выше флаг, чтобы использовать все флаги в этом файле вместе.
например:
Файл: compilerFlags
Затем скомпилируйте:
источник
-march=native
создать оптимизированный код для платформы (= чип), на которой вы компилируетеисточник
Если вам нужно знать флаги препроцессора, которые предопределены компилятором:
источник
Это не очень полезно для обнаружения ошибок, но редко упоминаемая
-masm=intel
опция делает использование-S
для проверки вывода сборки намного более приятным.Синтаксис сборки AT & T слишком сильно ранит мою голову.
источник
Мой make-файл обычно содержит
Наиболее важные из этих вариантов были обсуждены ранее, поэтому я укажу на две функции, которые еще не были указаны:
Несмотря на то, что я работаю над базой кода, которая должна быть простой C для переносимости на какую-то платформу, у которой все еще нет достойного компилятора C ++, я делаю «дополнительную» компиляцию с помощью компилятора C ++ (в дополнение к компилятору C). Это имеет 3 преимущества:
Да, я безнадежно оптимистичная Поллианна, которая постоянно думает, что в любой месяц наверняка одна платформа будет либо объявлена устаревшей, либо получит достойный компилятор C ++, и мы наконец сможем переключиться на C ++. На мой взгляд, это неизбежно - вопрос только в том, произойдет ли это до или после того, как руководство наконец выпустит всех пони. :-)
источник
источник
-Wold-style-definition
если вам приходится иметь дело с рецидивистами, которые считают, что функции в стиле K & R - хорошая идея, даже с объявлениями-прототипами. (Мне приходится иметь дело с такими людьми. Меня действительно раздражает, когда я нахожу новый код, написанный на K & R. Достаточно плохо иметь устаревшие K & R-материалы, которые не исправлены, но новый код! Grump !!!)Вот отличный флаг, который не был упомянут:
Выдает ошибку всякий раз, когда функция используется перед объявлением.
источник
Руководство полно интересных флагов с хорошими описаниями. Тем не менее, -Wall, вероятно, сделает GCC максимально подробным. Если вам нужны более интересные данные, вы должны взглянуть на valgrind или другой инструмент для проверки ошибок.
источник
man gcc | nl
сообщает более 11000 строк. Это больше, чем печально известнаяbash
страница!Ну,
-Wextra
должно быть стандартным тоже.-Werror
превращает предупреждения в ошибки (которые могут быть очень раздражающими, особенно если вы компилируете без них-Wno-unused-result
).-pedantic
в сочетании сstd=c89
дает вам дополнительные предупреждения, если вы используете функции C99.Но это все. Вы не можете настроить компилятор C на что-то более сохраняющее тип, чем сам C.
источник
-M*
Семья вариантов.Они позволяют вам писать make-файлы, которые автоматически выясняют, от каких файлов заголовков должны зависеть ваши исходные файлы c или c ++. GCC создаст файлы make с этой информацией о зависимостях, а затем вы включите их в свой основной файл make.
Вот пример чрезвычайно универсального make-файла с использованием -MD и -MP, который скомпилирует каталог, полный исходных и заголовочных файлов c ++, и автоматически определит все зависимости:
Вот запись в блоге, в которой это обсуждается более подробно: http://www.microhowto.info/howto/automatics_generate_makefile_dependencies.html
источник
Существует
-Werror
, который обрабатывает все предупреждения как ошибки и останавливает компиляцию. Страницаgcc
руководства объясняет каждый параметр командной строки для вашего компилятора.источник
gcc
флаги могут отличаться между вашей и любой ссылкой, которую кто-либо может предложить. Вот почему страницы руководства поставляются с вашим программным обеспечением.-Wfloat-equal
От: http://mces.blogspot.com/2005/07/char-const-argv.html
источник
Я обнаружил, что эта тема ищет флаг для решения конкретной проблемы, здесь его нет, поэтому я добавлю тот, который просто озадачил меня в моем сообщении :
-Wformat=2
флагИ действительно важная часть об этом ( согласно руководству GCC ):
Так что, только потому, что у вас есть
-Wall
, не значит, что у вас есть все. ;)источник
Я иногда использую
-s
для гораздо меньшего исполняемого файла:Источник: http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options
источник
strip
свой бинарный файл, таким образом, вы можете получить бинарный файл с отладочной информацией, затем удалить его для распространения.strip
тоже работает, но-s
может быть быстрее и проще, хотя и не так сложно, как бегstrip
Хотя этот ответ может быть немного не по теме и вопрос стоит от меня +1, так как
есть инструмент, который должен отлавливать ВСЕ ошибки и потенциальные ошибки, которые могут быть неочевидными, есть шину, которая, IMHO, делает лучшую работу по отлову ошибок по сравнению с gcc или любым другим компилятором в этом отношении. Это достойный инструмент в вашем сундуке с инструментами.Статическая проверка с помощью инструмента типа lint, такого как splint, должна была быть частью цепочки инструментов компилятора.
источник
В дополнение к
-Wall
, опция-W
or-Wextra
(-W
работает как с более старыми версиями gcc, так и с более новыми; более поздние версии поддерживают альтернативное имя-Wextra
, что означает то же самое, но более наглядно), включает различные дополнительные предупреждения.Есть также еще больше предупреждений, которые не включены ни одним из них, как правило, для более сомнительных вещей. Набор доступных опций зависит от того, какую версию gcc вы используете - обратитесь
man gcc
или обратитесьinfo gcc
за подробностями или посмотрите онлайн-документацию для конкретной интересующей вас версии gcc. И-pedantic
выдает все предупреждения, требуемые конкретным используемым стандартом (который зависит на другие параметры, такие как-std=xxx
или-ansi
), и жалуется на использование расширений gcc.-Werror
превращает все предупреждения в ошибки. Я не думаю, что gcc позволяет вам делать это выборочно для конкретных предупреждений.Вы, вероятно, обнаружите, что вам нужно выборочно выбирать, какие предупреждения включены для каждого проекта (особенно, если вы используете
-Werror
), поскольку заголовочные файлы из внешних библиотек могут отключить некоторые из них. (-pedantic
в частности, по моему опыту, в этом отношении бесполезно.)источник
-Werror=some-warning
.-Wmissing-prototypes
: Если глобальная функция определена без предыдущего объявления прототипа.-Wformat-security
: Предупреждает об использовании функций форматирования, которые представляют возможные проблемы безопасности. В настоящее время это предупреждает о вызовахprintf
иscanf
функциях, где строка формата не является строковым литералом и нет аргументов форматаисточник
-Werror=return-type
: Принудительная ошибка, когда функция не возвращает в gcc. Это/we4716
в Visual Studio.-Werror=implicit-function-declaration
: Принудительная ошибка, когда функция используется без определения / не включена. Это/we4013
в Visual Studio.-Werror=incompatible-pointer-types
: Ошибка выше, когда тип указателя не соответствует ожидаемому типу указателя. Это/we4133
в Visual Studio.На самом деле, я хотел бы сохранить свой C-код кроссплатформенным, и я использую CMake, и я помещаю предоставленные cflags в CMakeLists.txt, например:
источник