Флаги для включения подробных и подробных предупреждений g ++ - PullRequest
106 голосов
/ 23 февраля 2011

Часто в 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, если мне придется отойти во время компиляции.

Я просто беру C ++ (да, я на 15 лет отстал), и я бы хотел начать с правой ноги.

Мой вопрос: есть ли у кого-нибудь предварительно скомпилированный аналогичный набор флагов полного предупреждения для C ++ в g++? (Я знаю, что многие из них будут одинаковыми.)

Ответы [ 5 ]

117 голосов
/ 25 марта 2012

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

-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). Пример в моем коде где я использую это то, что у меня есть вектор с плавающей точкой. Я прохожу это вектор, и есть некоторые элементы, которые я пока не могу оценить, что они должно быть, поэтому я установил их на -1.0f (так как моя проблема использует только положительные числа, -1 вне домена). Я позже пройду и обновить значения -1.0f. Это не легко поддается другому метод операции. Я подозреваю, что у большинства людей этого нет проблема, и сравнение точного числа с плавающей точкой возможно ошибка, поэтому я включаю ее в список по умолчанию.

  • -Wold-style-cast содержит много ложных срабатываний в коде библиотеки, который я использую. В частности, семейство функций htonl, используемых в сети, а также реализация шифрования Rijndael (AES), которую я использую, имеют приведение в старом стиле, о которых меня предупреждает. Я намереваюсь заменить оба из них, но я не уверен, есть ли в моем коде что-то еще, на что он будет жаловаться. Большинство пользователей, вероятно, должны включить это по умолчанию.

  • -Wsign-conversion был сложным (и почти не делал список). Включение этого в моем коде вызвало огромное количество предупреждений (100+). Почти все они были невинны. Тем не менее, я был осторожно использовать целые числа со знаком, где я не был уверен, хотя для моя конкретная проблемная область, я обычно получаю небольшую эффективность увеличить с использованием беззнаковых значений из-за большого количества целых деление я делаю. Я пожертвовал этой эффективностью, потому что был обеспокоен о случайном продвижении подписанного целого числа без знака, а затем деление (что небезопасно, в отличие от сложения, вычитания и умножение). Включение этого предупреждения позволило мне безопасно изменить большинство моих переменных для неподписанных типов и добавить несколько приведения в некоторых другие места. В настоящее время это немного сложно использовать, потому что предупреждение не такой умный Например, если вы делаете unsigned short + (integral constant expression), этот результат неявно повышается до int. Это затем предупреждает о потенциальной проблеме со знаком, если вы присвоите это значение unsigned или unsigned short, хотя это безопасно. Это безусловно, самое дополнительное предупреждение для почти всех пользователей.

  • -Wsign-promo: см. -Wsign-conversion.

  • -Wswitch-default кажется бессмысленным (вы не всегда хотите по умолчанию на случай, если вы перечислили все возможности явно). Тем не мение,включение этого предупреждения может привести к тому, что это, вероятно, хорошая идея.В случаях, когда вы явно хотите игнорировать все, кроме перечисленных возможностей (но возможны и другие числа), введите default: break;, чтобы сделать это явным.Если вы явно перечислите все возможности, то включение этого предупреждения поможет вам установить что-то вроде assert (false), чтобы убедиться, что вы действительно охватили все возможные варианты.Это позволяет вам четко указывать, в чем заключается проблема, и программно обеспечивает это.Тем не менее, вы должны быть осторожны, просто вставляя утверждение (ложь) везде.Это лучше, чем ничего не делать со случаем по умолчанию, но, как обычно, с assert, он не будет работать в сборках релиза.Другими словами, вы не можете полагаться на него для проверки номеров, которые вы получаете, скажем, из сетевого подключения или базы данных, над которой у вас нет абсолютного контроля.Исключения или раннее возвращение - лучший способ справиться с этим (но все же вы должны иметь дело по умолчанию!).

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

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

Предупреждений, которые отсутствуют:

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

  • -Waggregate-return - это не то, что я считаю ошибкой.Например, он срабатывает при использовании цикла for на основе диапазона для вектора классов.Оптимизация возвращаемого значения должна позаботиться о любых негативных последствиях этого.

  • -Wconversion срабатывает в этом коде: short n = 0; n += 2; Неявное преобразование в int вызывает предупреждение, когда оно затем преобразуется обратно вего целевой тип.

  • -Weffc++ включает предупреждение, если все элементы данных не инициализированы в списке инициализатора.Я намеренно не делаю этого во многих случаях, поэтому набор предупреждений слишком загроможден, чтобы быть полезным.Полезно время от времени включать и сканировать другие предупреждения (например, не виртуальные деструкторы базовых классов).Это было бы более полезно, поскольку набор предупреждений (например, -Wall) вместо одного отдельного предупреждения.

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

  • -Winvalid-pch отсутствует, потому что я не использую предварительно скомпилированныйЗаголовки.

  • -Wmissing-format-attribute не используется, потому что я не использую расширения GNU.То же самое для -Wsuggest-attribute и некоторых других

  • Потенциально известно его отсутствие - -Wno-long-long, в котором я не нуждаюсь.Я компилирую с -std=c++0x (-std=c++11 в GCC 4.7), который включает в себя long long целочисленные типы.Те, кто застрял на C ++ 98 / C ++ 03, могут рассмотреть возможность добавления этого исключения из списка предупреждений.

  • -Wnormalized=nfc уже является вариантом по умолчанию и выглядит лучшим.

  • -Wpadded иногда включается для оптимизации макета классов, но не включается, потому что не все классы имеют достаточно элементов для удаления отступов в конце.Теоретически я мог бы получить некоторые дополнительные переменные для «free», но это не стоит дополнительных усилий для поддержания этого (если размер моего класса изменится, удалить эти ранее свободные переменные нелегко).

  • -Wstack-protector не используется, потому что я не использую -fstack-protector

  • -Wstrict-aliasing=3 включен -Wall и является наиболееточно, но похоже, что уровень 1 и 2 дают больше предупреждений.Теоретически, более низкий уровень является «более сильным» предупреждением, но за счет большего количества ложных срабатываний.Мой собственный тестовый код скомпилирован чисто на всех 3 уровнях.

  • -Wswitch-enum - это не то поведение, которое мне нужно.Я не хочу обрабатывать каждый оператор switch явно.Было бы полезно, если бы в языке был какой-то механизм для активации этого в указанных операторах switch (чтобы гарантировать, что будущие изменения в enum обрабатываются везде, где они должны быть), но для настройки «все или ничего» излишне.

  • -Wunsafe-loop-optimizations вызывает слишком много ложных предупреждений.Может быть полезно периодически применять этот метод и вручную проверять результаты.Например, он генерировал это предупреждение в моем коде, когда я зацикливался на всех элементах вектора, чтобы применить к ним набор функций (используя основанный на диапазоне цикл for).Это также предупреждение для конструктора const-массива const std :: string (где это не цикл в пользовательском коде).

  • -Wzero-as-null-pointer-constant и -Wuseless-cast - GCC-Предупреждения только для 4.7, которые я добавлю при переходе на GCC 4.7.

Я подал несколько отчетов об ошибках / запросов на улучшение в gcc в результате некоторых из этих исследований,так что, надеюсь, я смогу добавить больше предупреждений из списка «не включать» в список «включать».Этот список включает в себя все предупреждения, упомянутые в этой теме (плюс, я думаю, несколько дополнительных).Многие из предупреждений, явно не упомянутых в этом посте, включены как часть другого предупреждения, которое я упоминаю.Если кто-нибудь заметит какие-либо предупреждения, полностью исключенные из этого поста, сообщите мне.

edit: Похоже, я пропустил несколько (которые я сейчас добавил).На самом деле есть вторая страница в http://gcc.gnu.org, которая довольно хорошо спрятана. Общие параметры предупреждений и Параметры C ++ (прокрутите вниз, чтобы просмотреть предупреждения)

35 голосов
/ 23 февраля 2011

Да, все мои первоначальные поиски обнаружили 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

Итак, я думаю, что это хорошая отправная точка. Не понимал, что это обман, но, по крайней мере, он был глубоко похоронен. : -)

11 голосов
/ 23 февраля 2011

Некоторые из них уже включены в -Wall или -Wextra.

Хорошая базовая настройка для C:

-std=c99 -pedantic -Wall -Wextra -Wwrite-strings -Werror

и для C ++

-ansi -pedantic -Wall -Wextra -Weffc++

(пропуская -Werror для C ++, поскольку -Weffc++ имеет некоторые неудобства)

2 голосов
/ 02 апреля 2013

Попробуйте

export CFLAGS="`gcc --help=warnings | grep '\-W' | awk '{print $1 \" \"}' |
sort | uniq` -pedantic -fdiagnostics-show-option -Werror"

Это быстрый и грязный старт, который определенно потребует некоторой настройки; с одной стороны, даже если вы вызовете компилятор по имени, соответствующему вашему языку (например, g++ для C ++), вы получите предупреждения, которые не относятся к этому языку (и компилятор вскинет руки и откажется продолжайте, пока вы не удалите предупреждение).

Другое дело, что я добавил в -Werror, потому что, если вы не исправляете предупреждения, зачем вам их включать? Вы также можете убрать предупреждения из списка. (Например, я почти никогда не использую -Waggregate-return с C ++.)

Некоторые предупреждения ничего не сделают без других параметров, связанных с производительностью (-Wstack-protector). -fdiagnostics-show-option и руководство GCC - ваши друзья.

Кстати, некоторые предупреждения взаимоисключающие; в частности, использование -Wtraditional и -Wold-style-definition вместе с -Werror не компилируется.

0 голосов
/ 17 февраля 2019

В моем клионе CmakeLists.txt

cmake_minimum_required(VERSION 3.13)
project(cpp17)

set(CMAKE_CXX_STANDARD 17)

set(GCC_COVERAGE_COMPILE_FLAGS "-std=c++17 -Wall -Weffc++ -Wno-error=effc++ -pedantic \
 -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-newline-eof  \
-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")


set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}" )

add_executable(cpp17 main.cpp)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...