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