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



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




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


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



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

786   7  

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++ (и для которых руководящие принципы изменились в более поздних изданиях книги.) Я не хочу, чтобы меня предупреждали, что Я не инициализировал a std::string член в моем конструкторе; он имеет конструктор по умолчанию, который делает именно то, что я хочу, Почему я должен писать m_str() это назвать? Элемент -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+ актуалисты -м --помочь=предупреждения, вы можете даже указать --помочь=предупреждения,C, чтобы просто распечатать с соответствующих предупреждений.

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

Как использовать это довольно просто,в основном модуль, который вы включаете каждый предупреждающий флаг. И вы удаляете предупреждения по мере необходимости-некоторые из них действительно очень многословны. Пример:configure.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 но многие из них должен быть включено индивидуально.

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

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

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

Comments

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