Как включить (буквально) все предупреждения GCC?

Я хотел бы включить -- буквально -- все предупреждения ССЗ. (Можно подумать, что это будет легко...)

  • думаешь -Wall может сделать трюк, но нет! Еще нужно -Wextra.

  • думаешь -Wextra может сделать трюк, но нет! Не все из перечисленных предупреждений здесь (например, -Wshadow) включены этим. И я до сих пор не знаю, является ли этот список всесторонний.

как я могу сказать GCC включить (нет если, и или но!) все предупреждения он?

7 ответов


ты не можешь.

руководство для GCC 4.4.0 является исчерпывающим только для этой версии, но в нем перечислены все возможные предупреждения для 4.4.0. Однако они не все на странице, на которую вы ссылаетесь, например, некоторые языковые параметры находятся на страницах параметров C++ или Obj-C. Чтобы найти их все, вам лучше смотреть на!--19-->Параметры Резюме

поворачивая на все будет включать -Wdouble-promotion что актуально только на Процессоров с 32-разрядной одинарной точности с плавающей точкой блок, который реализует float в аппаратном обеспечении, но эмулирует double в программном обеспечении. Выполнение расчетов как double использовать эмуляцию программного обеспечения и медленнее. Это актуально для некоторых встроенных процессоров, но совершенно не актуально для современных настольных процессоров с аппаратной поддержкой 64-битной плавающей запятой.

еще одно предупреждение, которое обычно не полезно, это -Wtraditional, который предупреждает о прекрасно сформированном коде, который имеет другое значение (или не работает) в традиционном C, например "string " "concatenation", или определения функций ISO C! Вы действительно заботитесь о совместимости с 30-летнего компиляторы? Вы действительно хотите предупреждение для написания int inc(int i) { return i+1; } ?

я думаю -Weffc++ слишком шумно, чтобы быть полезным, он основан на устаревшем первом издании Эффективный C++ и предупреждает о конструкциях, которые являются совершенно действительными C++ (и для которых рекомендации изменились в более поздних изданиях книги.) Я не хочу, чтобы меня предупреждали, что Я не инициализировал std::string член в моем конструкторе; он имеет конструктор по умолчанию, который делает именно то, что я хочу, Почему я должен писать m_str() это назвать? The -Weffc++ предупреждения, которые были бы полезны, слишком сложны для компилятора, чтобы точно обнаружить (давая ложные негативы), а те, которые не полезны, такие как инициализация всех членов явно, просто производят слишком много шума, давая ложные срабатывания.

Люк Дантон предоставил пример of бесполезные предупреждения от -Waggregate-return это почти наверняка никогда не имеет смысла для кода C++.

то есть вы действительно не хотите все предупреждения, вы просто думаете, что вы делаете.

просмотрите руководство, прочитайте о них, решите,что вы можете включить, попробуйте их. Чтение руководства вашего компилятора-хорошая вещьTM в любом случае, короткий путь и включение предупреждений, которые вы не понимаете, не очень хорошая идея, особенно если это нужно, чтобы избежать RTFM.

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

некоторые предупреждения важны, а некоторые нет. Ты должен быть разборчивым, или ты испортишь свою программу. Рассмотрим, например, -Wdouble-promotion. Если вы работаете над встроенной системой, вам может понадобиться это; если вы работаете над настольной системой, вы, вероятно, этого не сделаете. И сделать вы хотите -Wtraditional? Сомневаюсь.

Edit: см. также -стены-все, чтобы включить все предупреждения который закрыт как WONTFIX.

Edit 2: в ответ на жалобу DevSolar о том, что makefiles должны использовать разные предупреждения в зависимости от версии компилятора, если -Wall -Wextra не подходит, тогда нетрудно использовать CFLAGS для компилятора и версии:

compiler_name := $(notdir $(CC))
ifeq ($(compiler_name),gcc)
compiler_version := $(basename $(shell $(CC) -dumpversion))
endif
ifeq ($(compile_name),clang)
compiler_version := $(shell $(CC) --version | awk 'NR==1{print $}')
endif
# ...
wflags.gcc.base := -Wall -Wextra
wflags.gcc.4.7 := -Wzero-as-null-pointer-constant
wflags.gcc.4.8 := $(wflags.gcc.4.7)
wflags.clang.base := -Wall -Wextra
wflags.clang.3.2 := -Weverything
CFLAGS += $(wflags.$(compiler_name).base) $(wflags.$(compiler_name).$(compiler_version))

Я бы согласился с предыдущими ответами, что, вероятно, не выгодно включать буквально все предупреждения, однако GCC предоставляет достаточно удобный способ достижения этого. Команда

gcc -Q --help=warning

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

gcc -Wall -Wextra -Q --help=warning

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

gcc -Q --help=warning | sed -e 's/^\s*\(\-\S*\)\s*\[\w*\]/ /gp;d' | tr -d '\n'

для моего текущего GCC это дает:

-Ваби -Ваби-тег -Waddress -Waggregate-возвращение -Waggressive-петля-оптимизация -Waliasing -Walign-Коммонс -Wampersand -Warray-границы -Warray-временные объекты -Wassign-перехват -Wattributes -Wbad-функция-монолитно-Wbool-сравнить -Wbuiltin-макро-пересмотрел -сан. узел++-совместимость -сан. узел++0х-совместимость -сан. узел++14-совместимости -сан. узел-привязка-тип -Wc90-С99-совместимость -Wc99-с11-совместимость -Wcast-выровнять -Wcast-кач -Тип данных wchar-подстрочные -Wcharacter-усечение -Wchkp -Wclobbered -Wcomment -Wcompare-реалс -Wconditionally-поддерживается-Wconversion -Wconversion-экстра-Wconversion-нуль -Wcoverage-несоответствие -Wcpp -Wctor-dtor-конфиденциальность-Wdate-время -Wdeclaration-после-заявление -Wdelete-неполные -Wdelete-невиртуальный-dtor -Wdeprecated -Wdeprecated-объявления -Wdesignated-инит-Wdisabled-оптимизация-Wdiscarded массива-отбор -Wdiscarded-отбор -данные-по-ноль -Wdouble-продвижение -Weffc++ -Wempty-тело -Wendif-этикетки -Wenum-сравнить -Wextra -Wfloat-равно -Wformat-содержит-нуль -Wformat-Дополнительно-Параметры -Wformat-небуквенный -Wformat-безопасности -Wformat-со знаком -Wformat-y2k -Wformat-ноль-длина -Wfree-остальной-объект -Wfunction-ликвидации -Wignored-отбор -Wimplicit -Wimplicit-функция-декларация -Wimplicit-инт -Wimplicit-интерфейс -Wimplicit-процедуры -Wincompatible-указателя-типы -Winherited вариативная-конструктор -Winit-собственной Винлайн -Уинт-преобразование -Уинт на указатель-монолитно-Wintrinsic-тень -Wintrinsics-СТД -Winvalid-памяти-модель -Winvalid-offsetof -Winvalid-ПЧ -Wjump-скучает-инит-Wline-усечение -Wliteral-суффикс -Wlogical-не-скобки -Wlogical-ОП -Wlong-Лонг -функции wmain -Wmaybe-неинициализированная -Wmemset-попутал-аргументы -Wmissing-брекеты -Wmissing-объявления -Wmissing-поле-инициализаторов -Wmissing-включать-изд -Wmissing-параметр-тип -Wmissing-прототипы -Wmultichar -Wnarrowing -Wnested-экстернов -Wnoexcept -Wnon-шаблон-друг -Wnon-виртуальный dtor -Wnonnull -Wodr -Волд-стиль-литой -Волд-стиль-декларации -Волд-стиль-определение -Wopenmp-Симд -Woverflow -Woverlength-струны -Woverloaded-виртуальный -Woverride-инит-Wpacked -Wpacked-битовое поле-совместимость -Wpadded -Wparentheses -Wpedantic -Wpmf-преобразования -Wpointer-arith -Wpointer-знак -Wpointer-на-Инт-каст-Wpragmas -Wproperty-назначить по умолчанию -Wprotocol -Wreal-в-постоянном -Wrealloc-лхс -Wrealloc-лхс-все -Wredundant-несколько деклараций -Wreorder -Wreturn-местные-Эл -Wreturn-тип -Wselector -Wsequence-поинт -Wshadow -Wshadow-Ивар -Wshift-счет-минус-Wshift-счет-перелив -Wsign-сравнить -Wsign-промо -Wsized-освобождение -Wsizeof-массив-аргумент -Wsizeof-указатель-memaccess -Wstack-протектор -устриц.-нуль-страж-устриц.-прототипы -устриц.-селектор-матч-Wsuggest-атрибут=сопзь Wsuggest-атрибут=формат -Wsuggest-атрибут=noreturn -Wsuggest-атрибут=чисто -Wsuggest-финал-методы -Wsuggest-финал-типа-Wsuggest-переопределить -Wsurprising -Wswitch -Wswitch-боол -Wswitch-по умолчанию -Wswitch-перечислимого -Wsync-памяти NAND -Wsynth -Wsystem-заголовки -Wtabs -Wtarget жизни -Wtraditional -Wtraditional-преобразования -Wtrampolines -Wtrigraphs -тип wtype-лимиты-Wundeclared-селектор -Wundef -Wunderflow -Wuninitialized -Wunknown-прагмы -Wunsafe-петля-оптимизация -Wunsuffixed-флоат-константы -Wunused -Wunused-но-установить-параметр -Wunused-но-набор переменных -Wunused-пустышка-аргумент -Wunused-функция -Wunused-метки -Wunused-местных типов,- Wunused-макросы -Wunused-параметр -Wunused-результат -Wunused-значение -Wunused-переменная -Wuse-не-только -Wuseless-монолитно-Wvarargs -Wvariadic-макросы -Wvector-управление-производительность -Wvirtual-ход-назначить -Wvla -Wvolatile-зарегистрируйтесь-ВАР -Wwrite-струны -Wzero-А-нуль-указатель-константа -Wzerotrip -frequire-возврат-заявление

теперь это можно использовать для вызова GCC, т. е.

gcc $(gcc -Q --help=warning | sed -e 's/^\s*\(\-\S*\)\s*\[\w*\]/ /gp;d' | tr -d '\n')

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


просто невозможно программировать со всеми включенными предупреждениями (если вы не собираетесь игнорировать их, но тогда зачем беспокоиться?). Например, предположим, что вы используете следующий набор флагов: -Wstrict-prototypes -Wtraditional.

даже с двумя включенными предупреждениями следующая программа будет жаловаться.

/tmp $ cat main.c 
int main(int argc, char **argv) {
    return 0;
}
/tmp $ gcc -Wstrict-prototypes -Wtraditional main.c 
main.c: In function ‘main’:
main.c:1:5: warning: traditional C rejects ISO C style function definitions [-Wtraditional]
 int main(int argc, char **argv) {
     ^

вы можете подумать: "Ну, тогда я буду использовать прототипы старого стиля". Нет, это не сработает.

/tmp $ cat main.c 
int main(argc, argv)
    int argc;
    char **argv;
{
    return 0;
}
/tmp $ gcc -Wstrict-prototypes -Wtraditional main.c 
main.c:1:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
 int main(argc, argv)
     ^

и нет, не указывая какой-либо прототип также неправильно, так как компилятор будут также жаловаться.

/tmp $ cat main.c 
int main() {
    return 0;
}
/tmp $ gcc -Wstrict-prototypes -Wtraditional main.c 
main.c:1:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
 int main() {
     ^

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

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

-Wabi -Wctor-dtor-privacy -Wnon-virtual-dtor -Wreorder -Weffc++ -Wstrict-null-sentinel -Wno-non-template-friend -Wold-style-cast -Woverloaded-virtual -Wno-pmf-conversions -Wsign-promo -Wextra -Wall -Waddress -Waggregate-return -Warray-bounds -Wno-attributes -Wno-builtin-macro-redefined -Wc++0x-compat -Wcast-align -Wcast-qual -Wchar-subscripts -Wclobbered -Wcomment -Wconversion -Wcoverage-mismatch -Wno-deprecated -Wno-deprecated-declarations -Wdisabled-optimization -Wno-div-by-zero -Wempty-body -Wenum-compare -Wno-endif-labels -Wfatal-errors -Wfloat-equal -Wformat -Wformat=2 -Wno-format-contains-nul -Wno-format-extra-args -Wformat-nonliteral -Wformat-security -Wformat-y2k -Wignored-qualifiers -Winit-self -Winline -Wno-int-to-pointer-cast -Wno-invalid-offsetof -Winvalid-pch -Wunsafe-loop-optimizations -Wlogical-op -Wlong-long -Wmain -Wmissing-braces -Wmissing-field-initializers -Wmissing-format-attribute -Wmissing-include-dirs -Wmissing-noreturn -Wno-mudflap -Wno-multichar -Wnonnull -Wno-overflow -Woverlength-strings -Wpacked -Wpacked-bitfield-compat -Wpadded -Wparentheses -Wpointer-arith -Wredundant-decls -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wsign-conversion -Wstack-protector -Wstrict-aliasing=1 -Wstrict-overflow=5 -Wswitch -Wswitch-default -Wswitch-enum -Wsync-nand -Wsystem-headers -Wtrigraphs -Wtype-limits -Wundef -Wuninitialized -Wunknown-pragmas -Wno-pragmas -Wunreachable-code -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wvariadic-macros -Wvla -Wvolatile-register-var -Wwrite-strings

кто-то создал набор инструментов для определения полное набор предупреждений для данной версии GCC или Clang.

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

инструмент, похоже, анализирует фактический c.opt файл в исходном коде GCC, так что его результаты должны быть окончательным.

репозиторий также содержит текстовые файлы со списками предупреждений, сгенерированными для большинства версий GCC и Clang (в настоящее время Clang 3.2-3.7 и GCC 3.4-5.3).

https://github.com/barro/compiler-warnings


Gcc 4.3+ nows-Q --help=warnings, вы даже можете указать --help=warnings, C, чтобы просто распечатать предупреждения, связанные с C.

Я только что написал модуль m4, чтобы воспользоваться этим (также поддерживает clang's-Weverything), см. wget_manywarnings.М4

Как использовать его довольно просто, в основном модуль, который вы включаете каждый флаг предупреждения. И вы удаляете предупреждения по мере необходимости - некоторые действительно очень многословны. Пример: настройка.ac

Если вы не используете autotools, вы найдете код для включения всех отключенных предупреждений в модуле m4, который в основном является вызовом gcc, передаваемым через awk:

flags="-Wall -Wextra -Wformat=2 "$(gcc -Wall -Wextra -Wformat=2 -Q --help=warning,C|awk '{ if (( == "[disabled]" || == "") && !~/=/ && ~/^-W/&& !="-Wall") print }'


С на этой странице:

обратите внимание, что некоторые предупреждающие флаги не подразумевается -Wall. Некоторые из их предупреждать о конструкциях, которые пользователи обычно не рассматривают сомнительно, но иногда вы можете захотеть проверить; другие предупреждают о конструкциях, которые необходимо или трудно избежать в некоторые случаи, и нет простого способа изменить код для подавления предупреждение. Некоторые из них включены с помощью -Wextra но многие из них должен быть включено индивидуально.

Я думаю, вопрос какие? Возможно, вы могли бы ... --14-->grep эта страница для всех строк, начинающихся с-W, и получить полный список предупреждающих флагов. Затем сравните их со списками в разделе -Wall и -Wextra. Существует также -Wpedantic, хотя вы, очевидно, хотите быть еще более педантичным еще=)


и я до сих пор не знаю, является ли этот список полным.

вероятно, это так, но единственный список, который является 100% полным, является фактическим источником для компилятора. Однако, GCC-это большой! И я не знаю, собраны ли все параметры командной строки в одном месте или распределены по нескольким исходным файлам. Также обратите внимание, что некоторые предупреждения предназначены для предварительного процессора, некоторые для фактического компилятора и некоторые для компоновщика (который является полностью отдельным программа, и найдена в пакете binutils), поэтому они, скорее всего, разбросаны.