Флаги для тщательного и подробного предупреждения г++
часто в 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++? (Я знаю, что многие из них будут одинаковыми.)
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-castare 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