Флаги для включения подробных и подробных предупреждений 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, не будет компилироваться.