Флаги для тщательного и подробного предупреждения г++



часто в 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++? (Я знаю, что многие из них будут одинаковыми.)

599   4  

4 ответов:

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

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

  • -Wfloat-equal предупреждает для безопасных сравнений равенства (в частности, сравнение с не вычисленным значением -1). Пример в моем коде где я использую это то, что у меня есть вектор float. Я иду через это вектор, и есть некоторые элементы, которые я пока не могу оценить, что они должно быть, поэтому я установил их -1.0 f (так как моя проблема использует только положительные числа, -1 находится вне области). Я позже пройду и обновление значения f -1.0. Он не легко поддается различным порядок эксплуатации. Я подозреваю, что у большинства людей этого нет проблема, и сравнение точного числа в плавающей точке является вероятно, ошибка, поэтому я включаю его в список по умолчанию.

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

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

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

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

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

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

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

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

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

  • -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 иногда включается для оптимизации макета из классы, но не остался, потому что не все классы хватает элементы для удаления прокладки в конце. В теории я мог бы получить некоторые дополнительные переменные для "бесплатно", но это не стоит дополнительных усилий поддержание этого (если мой размер класса изменяется, его нелегко удалить те ранее свободные переменные).

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

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

  • -Wswitch-enum - это не поведение, что я хочу. Я не хочу с этим разбираться каждый оператор switch явно. Было бы полезно, если бы язык имел некоторый механизм для активации этого на указанных операторах коммутатора (чтобы гарантировать, что будущие изменения перечисления обрабатываются везде что они должны быть), но это перебор для "ВСЕ-ИЛИ-НИЧЕГО" установочный.

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

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

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

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

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

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

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

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

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

и для C++

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

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

попробовать

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

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

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

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

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

Comments

    Ничего не найдено.