Флаги для включения подробных и подробных предупреждений g++
Часто в C под gcc
, я начну со следующего набора предупреждающих флагов (мучительно собранных из нескольких источников):
-Wall -Wextra -Wformat-nonliteral -Wcast-align -Wpointer-arith -Wbad-function-cast \
-Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -Winline -Wundef \
-Wnested-externs -Wcast-qual -Wshadow -Wwrite-strings -Wno-unused-parameter \
-Wfloat-equal -pedantic -ansi
Я построю (по крайней мере, мои версии отладки) с этим набором предупреждений и исправлю все, что возможно (обычно все), а затем удаляю только флаги, если они либо не актуальны, либо не исправляются (почти никогда не бывает). Иногда я также добавляю -Werror
, если мне нужно отступить при компиляции.
Я просто подбираю С++ (да, я нахожусь на 15 лет позади), и я бы хотел начать с правой ноги.
Мой вопрос: у кого-то есть предварительно скомпилированный подобный набор полных предупреждающих флагов для С++ под g++
? (Я знаю, что многие из них будут одинаковыми.)
Ответы
Ответ 1
D'oh, все мои первоначальные поиски поднялись на 99% сообщений о том, как подавлять предупреждения (достаточно много), но я просто пробежал этот комментарий, который имеет этот прекрасный набор флагов (некоторые менее релевантные):
Перекрестная проверка:
http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
-g -O -Wall -Weffc++ -pedantic \
-pedantic-errors -Wextra -Waggregate-return -Wcast-align \
-Wcast-qual -Wconversion \
-Wdisabled-optimization \
-Werror -Wfloat-equal -Wformat=2 \
-Wformat-nonliteral -Wformat-security \
-Wformat-y2k \
-Wimplicit -Wimport -Winit-self -Winline \
-Winvalid-pch \
-Wlong-long \
-Wmissing-field-initializers -Wmissing-format-attribute \
-Wmissing-include-dirs -Wmissing-noreturn \
-Wpacked -Wpadded -Wpointer-arith \
-Wredundant-decls \
-Wshadow -Wstack-protector \
-Wstrict-aliasing=2 -Wswitch-default \
-Wswitch-enum \
-Wunreachable-code -Wunused \
-Wunused-parameter \
-Wvariadic-macros \
-Wwrite-strings
Итак, я считаю, что хорошая отправная точка. Не понял, что это был обман, но, по крайней мере, он был глубоко похоронен.: -)
Ответ 2
Я прошел и нашел минимальный набор включений, который должен получить максимальный уровень предупреждения. Затем я удаляю из этого списка набор предупреждений, которые, как я чувствую, фактически не указывают на то, что происходит что-то плохое, или слишком много ложных срабатываний, которые будут использоваться в реальной сборке. Я прокомментировал, почему каждый из исключенных я исключал. Это мой последний набор предлагаемых предупреждений:
-pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Werror -Wno-unused
Составляющие сомнительные предупреждения:
-
Я включаю -Wno-unused
, потому что у меня часто есть переменные, которые я знаю.
будут использоваться позже, но еще не имеют функциональности, написанной для.
Удаление предупреждений об этом позволяет мне писать в моем предпочтительном стиле
иногда откладывая реализацию вещей. Это полезно
каждый раз отключаться, чтобы убедиться, что ничего не поскользнулся
через трещины.
-
-Wdisabled-optimization
кажется сильным пользовательским предпочтением
установка. Я просто добавил это в свою сборку (только для оптимизированных построений
по очевидным причинам), и он ничего не менял, поэтому он не
кажется, особенно болтливым предупреждением, по крайней мере, для того, как я кодирую.
Я включаю его (даже если код, вызывающий это предупреждение, не является
обязательно неправильно), потому что я верю в работу с моими инструментами вместо
против них. Если gcc сообщает мне, что он не может оптимизировать код
для того, как я это написал, тогда я должен посмотреть на его переписывание. Я подозреваю
этот код, вызывающий это предупреждение, может выиграть от более
модульный, независимо от того, хотя код не является технически неправильным
(вероятно), стилистически это, вероятно, есть.
-
-Wfloat-equal
предупреждает о безопасном сравнении сравнений (в частности,
сравнение с не вычисленным значением -1). Пример в моем коде
где я использую это, что у меня есть вектор float. Я прохожу через это
вектор, и есть некоторые элементы, которые я еще не могу оценить, что они
должен быть, поэтому я устанавливаю их в -1.0f (поскольку моя проблема только использует
положительные числа, -1 вне домена). Позже я
обновить значения -1.0f. Это не легко поддается другому
метод работы. Я подозреваю, что у большинства людей этого нет
проблема и сравнение точного числа в плавающей точке
вероятно, ошибка, поэтому я включаю его в список по умолчанию.
-
-Wold-style-cast
имеет множество ложных срабатываний в библиотечном коде, который я использую. В частности, семейство функций htonl, используемых в сетях, а также реализация шифрования Rijndael (AES), которые я использую, имеют старомодные приведения, о которых она меня предупреждает. Я намерен заменить оба эти, но я не уверен, есть ли что-нибудь еще в моем коде, на которое он будет жаловаться. Однако большинство пользователей должны иметь это по умолчанию.
-
-Wsign-conversion
был жестким (и почти не сделал
список). Включение этого кода привело к огромному количеству предупреждений
(100+). Почти все они были невиновными. Однако я был
осторожно использовать целые числа со знаком, где бы я не был уверен, хотя для
моя конкретная проблемная область, я обычно получаю небольшую эффективность
увеличение с использованием неподписанных значений из-за большого количества целых чисел
раздел. Я пожертвовал этой эффективностью, потому что был обеспокоен
о случайном продвижении знакового целого к unsigned, а затем
(что небезопасно, в отличие от сложения, вычитания и
умножение). Включение этого предупреждения позволило мне безопасно изменить
большинство моих переменных для неподписанных типов и добавить несколько отливок в некоторые
другие места. В настоящее время это немного сложно использовать, поскольку предупреждение
не так уж и умный. Например, если вы выполняете unsigned short + (integral
constant expression)
, этот результат неявно продвигается до int. Это
затем предупреждает о потенциальной проблеме знака, если вы присваиваете этому значению значение
unsigned
или unsigned short
, даже если он безопасен. Это
безусловно, наиболее необязательное предупреждение для почти всех пользователей.
-
-Wsign-promo
: см. -Wsign-conversion
.
-
-Wswitch-default
кажется бессмысленным (вы не всегда хотите по умолчанию
если вы перечисляете все возможности явно). Однако,
включение этого предупреждения может привести к чему-то, что, вероятно, является хорошим
идея. В случаях, когда вы явно хотите игнорировать все, кроме
перечисленные возможности (но возможны и другие числа), затем
в default: break;
, чтобы сделать его явным. Если вы явно перечисляете
все возможности, то включение этого предупреждения поможет
вы ставите что-то вроде assert (false), чтобы убедиться, что вы
фактически охватывал все возможные варианты. Это позволяет вам четко указывать
какой предмет вашей проблемы и программно обеспечивает это.
Тем не менее, вы должны быть осторожны, просто придерживаясь assert (false)
везде. Это лучше, чем ничего не делать со случаем по умолчанию, но
как обычно, с утверждением, он не будет работать в сборках релизов. В других
слова, вы не можете полагаться на это, чтобы проверять числа, которые вы получаете,
скажем, сетевое соединение или базу данных, в которой у вас нет абсолютного
контроль над. Исключения или раннее возвращение - лучший способ
(но все равно требуйте, чтобы у вас был случай по умолчанию!).
-
-Werror
является важным для меня. При составлении большого количества
кода в многопоточной сборке с несколькими целями, это легко для
предупреждение проскальзывать. Превращение предупреждений в ошибки гарантирует, что я
обратите внимание на них.
Тогда есть набор предупреждений, которые не включены в список выше, потому что я не нашел их полезными. Это предупреждения и мои комментарии о том, почему я не включаю их в список по умолчанию:
Предупреждения, которые отсутствуют:
-
-Wabi
не требуется, потому что я не комбинирую двоичные файлы из разных компиляторов. Я все равно пытался скомпилировать его, и он не запускался, поэтому он не выглядит излишне подробным.
-
-Waggregate-return
- это не то, что я считаю ошибкой. Для
instance, он запускается при использовании цикла, основанного на диапазоне, для вектора
классов. Оптимизация возвращаемого значения должна заботиться о любых
негативные последствия этого.
-
-Wconversion
триггеры для этого кода: short n = 0; n += 2;
неявное преобразование в int вызывает предупреждение, когда оно затем преобразуется
вернуться к целевому типу.
-
-Weffc++
содержит предупреждение, если все члены данных не инициализированы
в списке инициализаторов. Я намеренно не делаю этого во многих
поэтому набор предупреждений слишком загроможден, чтобы быть полезным. Это
полезно включать каждый раз в то время и сканировать другие предупреждения,
хотя (например, не виртуальные деструкторы базовых классов). Это
более полезны в виде набора предупреждений (например, -Wall
) вместо
одно предупреждение само по себе.
-
-Winline
отсутствует, потому что я не использую ключевое слово inline для
оптимизации, просто для определения функций, входящих в заголовки. я
не волнует, действительно ли оптимизатор это делает. Это предупреждение также
жалуется, если он не может встроить функцию, объявленную в тело класса
(например, пустой виртуальный деструктор).
-
-Winvalid-pch
отсутствует, потому что я не использую предварительно скомпилированные заголовки.
-
-Wmissing-format-attribute
не используется, потому что я не использую gnu
расширения. То же самое для -Wsuggest-attribute
и нескольких других
-
Потенциально заметным для его отсутствия является -Wno-long-long
, который у меня есть
не нужно. Я компилирую с -std=c++0x
(-std=c++11
в GCC 4.7),
который включает в себя long long
целые типы. Они застряли на С++ 98/
С++ 03 может рассмотреть возможность добавления исключения из списка предупреждений.
-
-Wnormalized=nfc
уже является параметром по умолчанию и выглядит как
лучше всего.
-
-Wpadded
время от времени используется для оптимизации компоновки
классов, но это не осталось, потому что не все классы достаточно
элементы для удаления дополнений в конце. В теории я мог бы получить некоторые
дополнительные переменные для "свободных", но это не стоит дополнительных усилий
что (если мой размер класса изменяется, его нелегко удалить
те ранее свободные переменные).
-
-Wstack-protector
не используется, потому что я не использую -fstack-protector
-
-Wstrict-aliasing=3
включается -Wall
и является наиболее
точнее, но похоже, что уровни 1 и 2 дают больше предупреждений. В
теория более низкого уровня является "более сильным" предупреждением, но она ценой
более ложных срабатываний. Мой собственный тестовый код скомпилирован под всеми 3
уровни.
-
-Wswitch-enum
- это не поведение, которое я хочу. Я не хочу обращаться
каждый оператор switch явно. Было бы полезно, если бы язык
имел некоторый механизм для активации этого на указанных операторах switch
(чтобы гарантировать, что будущие изменения в перечислении будут обрабатываться повсюду
что они должны быть), но он переполняет "все или ничего",
установка.
-
-Wunsafe-loop-optimizations
вызывает слишком много ложных предупреждений. Это
может быть полезно периодически применять эту процедуру и вручную проверять
Результаты. Например, он сгенерировал это предупреждение в моем коде, когда я
зацикливается на всех элементах вектора, чтобы применить набор функций к
их (используя цикл, основанный на диапазоне). Это также предупреждение для
конструктор массива const из const std::string (где это нет
цикл в коде пользователя).
-
-Wzero-as-null-pointer-constant
и -Wuseless-cast
являются
Предупреждения GCC-4.7, которые я буду добавлять при переходе на GCC 4.7.
В результате некоторых исследований я подал несколько сообщений об ошибках/улучшениях в gcc, поэтому надеюсь, что в конечном итоге я смогу добавить больше предупреждений из списка "не включать" в список "не включать", включить "список. Этот список включает все предупреждения, упомянутые в этом разделе (плюс, я думаю, несколько дополнительных). Многие предупреждения, явно не упомянутые в этом сообщении, включены как часть другого предупреждения, о котором я упоминаю. Если кто-либо замечает какие-либо предупреждения, которые полностью исключены из этого сообщения, сообщите мне.
edit: Похоже, я пропустил несколько (которые я теперь добавил). Фактически на странице http://gcc.gnu.org есть вторая страница, которая довольно хорошо скрыта. Общие предупреждения и Параметры С++ (прокрутите вниз до нижней части предупреждений)
Ответ 3
Некоторые из них уже включены в -Wall
или -Wextra
.
Хорошая базовая настройка для C:
-std=c99 -pedantic -Wall -Wextra -Wwrite-strings -Werror
и для С++
-ansi -pedantic -Wall -Wextra -Weffc++
(пропуская -Werror
для С++, так как -Weffc++
имеет некоторые досады)
Ответ 4
Try
export CFLAGS="`gcc --help=warnings | grep '\-W' | awk '{print $1 \" \"}' |
sort | uniq` -pedantic -fdiagnostic-show-option -Werror"
Это быстрый и грязный старт, который определенно нуждается в некоторой настройке; во-первых, даже если вы вызываете компилятор по соответствующему имени для вашего языка (например, g++ для С++), вы получите предупреждения, которые не относятся к этому языку (и компилятор выкинет руки и откажется продолжить пока вы не удалите предупреждение).
Другое дело, что я добавил в -Werror, потому что, если вы не исправляете предупреждения, зачем вам их включать? Вы также можете вывести предупреждения из списка (например, я почти никогда не использую -Waggregate-return
с С++).
Некоторые предупреждения ничего не сделают без других параметров, связанных с производительностью (-Wstack-protector
). -fdiagnostic-show-option
и руководство GCC - ваши друзья.
Кстати, некоторые предупреждения являются взаимоисключающими; в частности, используя -Wtraditional
и -Wold-style-definition
вместе с -Werror
, не будет компилироваться.