Полезный GCC отмечает для C

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

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

154
задан Matt Joiner 30 July 2010 в 22:04
поделиться

19 ответов

Интересны несколько вариантов генерации кода -f :

  • Функция -ftrapv заставит программу прерваться при переполнении целого числа со знаком. (формально «неопределенное поведение» в C).

  • -fverbose-asm полезен, если вы компилируете с помощью -S для проверки вывода сборки - он добавляет некоторые информативные комментарии.

  • -finstrument-functions добавляет код для вызова пользовательских функций профилирования в каждой точке входа и выхода функции.

64
ответ дан 23 November 2019 в 21:58
поделиться

Меня особенно интересуют любые дополнительные предупреждения,

В дополнение к -Wall , -W или -Wextra Параметр ( -W работает как со старыми версиями gcc, так и с более новыми; более свежие версии поддерживают альтернативное имя -Wextra , что означает то же самое, но больше описательный) включает различные дополнительные предупреждения.

Есть также еще больше предупреждений, которые не активируются ни одним из них, как правило, для более сомнительно плохих вещей. Набор доступных параметров зависит от того, какую версию gcc вы используете - обратитесь к man gcc или info gcc , чтобы узнать подробности, или см. онлайн-документацию для получения более подробной информации. Версия gcc, которая вас интересует. А -pedantic выдает все предупреждения, требуемые конкретным используемым стандартом (что зависит от других параметров, таких как -std = xxx или - ansi ) и жалуется на использование расширений gcc.

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

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

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

2
ответ дан 23 November 2019 в 21:58
поделиться

Существует -Werror , которая обрабатывает все предупреждения как ошибки и останавливает компиляцию. На странице руководства gcc описаны все параметры командной строки для вашего компилятора.

6
ответ дан 23 November 2019 в 21:58
поделиться
man gcc

В руководстве много интересных флагов с хорошими описаниями. Однако -Wall, вероятно, сделает gcc максимально подробным. Если вам нужны более интересные данные, вам следует взглянуть на valgrind или какой-либо другой инструмент для проверки ошибок.

8
ответ дан 23 November 2019 в 21:58
поделиться

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

15
ответ дан 23 November 2019 в 21:58
поделиться

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

35
ответ дан 23 November 2019 в 21:58
поделиться

Иногда я использую -s для гораздо меньшего исполняемого файла:

-s
    Remove all symbol table and relocation information from the executable.

Источник: http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options

3
ответ дан 23 November 2019 в 21:58
поделиться

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

echo | gcc -E -dM -
14
ответ дан 23 November 2019 в 21:58
поделиться

Ну, -Wextra тоже должна быть стандартной. -Werror превращает предупреждения в ошибки (что может быть очень раздражающим, особенно если вы компилируете без -Wno-unused-result ). -pedantic в сочетании с std = c89 выдает дополнительные предупреждения, если вы используете функции C99.

Но это все. Вы не можете настроить компилятор C на что-то более сохраняющее тип, чем сам C.

6
ответ дан 23 November 2019 в 21:58
поделиться

Вот мои:

  • -Wextra, -Wall: существенно.
  • -Wfloat-equal: полезно, потому что обычно проверка чисел с плавающей точкой на равенство - это плохо.
  • -Wundef: предупреждение, если неинициализированный идентификатор оценивается в директиве #if.
  • -Wshadow: предупреждение, когда локальная переменная затеняет другую локальную переменную, параметр или глобальную переменную или когда затеняется встроенная функция.
  • -Wpointer-arith: предупреждать, если что-либо зависит от размера функции или void.
  • -Wcast-align: предупреждать всякий раз, когда указатель приводится так, что требуемое выравнивание цели увеличивается. Например, предупреждение, если char * приводится к int * на машинах, где доступ к целым числам возможен только через двух- или четырехбайтовые границы.
  • -Wstrict-prototypes: предупреждать, если функция объявлена или определена без указания типов аргументов.
  • -Wstrict-overflow=5: предупреждает о случаях, когда компилятор оптимизирует, основываясь на предположении, что знаковое переполнение не произойдет. (Значение 5 может быть слишком строгим, см. страницу руководства).
  • -Wwrite-strings: присваивает строковым константам тип const char[length], так что копирование адреса одной из них в указатель неconst char * получит предупреждение.
  • -Waggregate-return: предупреждение, если определены или вызваны функции, возвращающие структуры или объединения.
  • -Wcast-qual: предупреждение всякий раз, когда указатель приводится для удаления квалификатора типа из целевого типа*.
  • -Wswitch-default: предупреждать, когда оператор switch не имеет default case*.
  • -Wswitch-enum: предупреждать всякий раз, когда оператор switch имеет индекс перечислимого типа и не имеет case для одного или более именованных кодов этого перечисления*.
  • -Wconversion: предупреждение для неявных преобразований, которые могут изменить значение*.
  • -Wunreachable-code: предупреждение, если компилятор обнаруживает, что код никогда не будет выполнен*.

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

135
ответ дан 23 November 2019 в 21:58
поделиться
-Wstrict-prototypes -Wmissing-prototypes
9
ответ дан 23 November 2019 в 21:58
поделиться

Всегда используйте -O или выше (-O1, -O2, -Os и т.д.). При уровне оптимизации по умолчанию gcc стремится к скорости компиляции и не делает достаточного анализа, чтобы предупредить о таких вещах, как унифицированные переменные.

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

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

Предупреждения, включенные в -Wextra, обычно отмечают обычный, легитимный код. Они могут быть полезны при обзоре кода (хотя программы в стиле lint находят гораздо больше подводных камней, они более гибкие), но я бы не стал включать их при обычной разработке.

-Wfloat-equal - хорошая идея, если разработчики проекта незнакомы с плавающей запятой, и плохая, если знакомы.

-Winit-self полезен; интересно, почему он не включен в -Wuninitialized.

-Wpointer-arith полезен, если у вас есть в основном переносимый код, который не работает с -pedantic.

52
ответ дан 23 November 2019 в 21:58
поделиться

-Wfloat-equal

From: http://mces.blogspot.com/2005/07/char-const-argv.html

One of the other new warnings that I like is the -Wfloat-equal. That one warns whenever you [have] a floating-point number in an equality condition. That's briliant! If you have every programmed a computer graphics or (worse:) computational geometry algorithm, you know that no two floats ever match with equality...

4
ответ дан 23 November 2019 в 21:58
поделиться

Это не очень полезно для обнаружения ошибок, но редко упоминаемая опция -masm = intel делает использование -S для проверки вывода сборки намного лучше.

Синтаксис ассемблера AT&T слишком разбивает мне голову.

13
ответ дан 23 November 2019 в 21:58
поделиться

-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
35
ответ дан 23 November 2019 в 21:58
поделиться

Хотя этот ответ может быть немного не по теме, и вопрос стоит от меня +1, так как

меня особенно интересуют любые дополнительные предупреждения и / или предупреждения о включении в ошибки в некоторых случаях, чтобы полностью свести к минимуму любые случайные несоответствия типов.
есть инструмент, который должен вылавливать ВСЕ ошибки и потенциальные ошибки, которые могут быть неочевидными, есть splint , который, ИМХО, лучше справляется с поиском ошибок по сравнению с gcc или любой другой компилятор в этом отношении. Это достойный инструмент, который стоит иметь в вашем ящике с инструментами.

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

3
ответ дан 23 November 2019 в 21:58
поделиться
-save-temps

При этом остаются результаты работы препроцессора и ассемблера.

Препроцессированный исходный текст полезен для отладки макросов.

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

38
ответ дан 23 November 2019 в 21:58
поделиться

Мой make-файл обычно содержит

  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 ++. На мой взгляд, это неизбежно - вопрос только в том, произойдет ли это до или после того, как руководство наконец выдаст всем пони. : -)

10
ответ дан 23 November 2019 в 21:58
поделиться

Вот отличный флаг, о котором не упоминалось:

-Werror-implicit-function-declaration

Выдавать ошибку всякий раз, когда функция используется перед ее объявлением.

9
ответ дан 23 November 2019 в 21:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: