web-dev-qa-db-fra.com

Comment activer (littéralement) TOUS les avertissements de GCC?

Je voudrais activer - littéralement - [~ # ~] tous [~ # ~] des avertissements que GCC a. (On pourrait penser que ce serait facile ...)

  • Vous penseriez -Wall _ pourrait faire l'affaire, mais non! Toujours besoin -Wextra.

  • Vous penseriez -Wextra _ pourrait faire l'affaire, mais non! Tous les avertissements répertoriés ici (par exemple, -Wshadow) sont activés par ceci. Et je ne sais toujours pas si cette liste est exhaustive.

Comment puis-je dire à GCC d'activer (non si, et, ou si!) tous les avertissements dont il dispose?

172
Mehrdad

Tu ne peux pas.

Le manuel de GCC 4.4.0 n’est exhaustif que pour cette version, mais il répertorie tous les avertissements possibles pour 4.4.0. Elles ne figurent pas toutes sur la page à laquelle vous créez un lien, par exemple, certaines options spécifiques à une langue figurent sur les pages pour les options C++ ou Obj-C. Pour les trouver tous, vous feriez mieux de regarder le Résumé des options

Activer tout inclurait -Wdouble-promotion, Qui ne concerne que les CPU avec une unité à virgule flottante simple précision 32 bits qui implémente float dans le matériel, mais émule dans le logiciel double. Effectuer des calculs en tant que double utiliserait l'émulation logicielle et serait plus lent. Ceci est pertinent pour certains processeurs intégrés, mais totalement inutile pour les processeurs de bureau modernes avec prise en charge matérielle pour virgule flottante 64 bits.

Un autre avertissement qui n’est généralement pas utile est -Wtraditional, Qui avertit d’un code parfaitement formé qui a une signification différente (ou ne fonctionne pas) en C traditionnel, par exemple. "string " "concatenation", Ou définitions de fonction ISO C! Vous souciez-vous vraiment de la compatibilité avec les compilateurs de 30 ans? Voulez-vous vraiment un avertissement pour l'écriture int inc(int i) { return i+1; }?

Je pense que -Weffc++ Est trop bruyant pour être utile, il est basé sur la première version obsolète de Effective C++ et met en garde sur les constructions qui sont parfaitement valides C++ (et pour lesquelles les directives ont changé dans les éditions ultérieures du livre.) Je ne veux pas être averti que je n’ai pas initialisé un membre std::string dans mon constructeur; il a un constructeur par défaut qui fait exactement ce que je veux, pourquoi devrais-je écrire m_str() pour l'appeler? Les avertissements -Weffc++ Qui seraient utiles sont trop difficiles à détecter avec précision par le compilateur (donner de faux négatifs), et ceux qui ne sont pas utiles, tels que l’initialisation explicite de tous les membres, ne produisent que trop de bruit, donnant faux positifs.

Luc Danton a fourni un bon exemple d'avertissements inutiles de -Waggregate-return Qui n'ont presque jamais de sens pour le code C++.

c'est-à-dire que vous ne voulez pas vraiment tous avertissements, vous pensez juste que vous voulez.

Parcourez le manuel, lisez-les, choisissez ce que vous voulez activer, essayez-les. Lire le manuel de votre compilateur est une bonne choseTM Quoi qu'il en soit, prendre un raccourci et activer des avertissements que vous ne comprenez pas n'est pas une très bonne idée, surtout si c'est pour éviter d'avoir à utiliser RTFM.

Toute personne qui allume simplement tout le fait probablement parce qu'ils ne savent rien ou parce qu'un patron aux cheveux pointus a dit "pas d'avertissements."

Certains avertissements sont importants, d'autres non. Vous devez faire preuve de discernement ou vous allez gâcher votre programme. Considérez, par exemple, -Wdouble-promotion. Si vous travaillez sur un système embarqué, vous pourriez Si vous travaillez sur un ordinateur de bureau, vous n’en avez probablement pas besoin et voulez-vous -Wtraditional? J'en doute.

Edit: Voir aussi - Wall-all pour activer tous les avertissements qui est fermé en tant que WONTFIX.

Edit 2: en réponse à la plainte de DevSolar selon laquelle les makefiles doivent utiliser des avertissements différents selon la version du compilateur, si -Wall -Wextra Ne convient pas, CFLAGS spécifique au compilateur et à la version n’est pas difficile à utiliser:

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 $$3}')
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))
116
Jonathan Wakely

Je conviens avec les réponses précédentes qu'il n'est probablement pas avantageux d'activer littéralement tous les avertissements, mais GCC fournit un moyen raisonnablement pratique d'y parvenir. La commande

gcc -Q --help=warning

fournit une liste de toutes les options d'avertissement prises en charge avec des informations indiquant si elles sont actives. Cela peut par ailleurs être utilisé pour déterminer quelles options sont activées (par exemple). -Wall Et -Wextra

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

Pour activer tous les avertissements, vous pouvez utiliser des expressions rationnelles pour extraire les paramètres de ligne de commande.

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

Pour mon GCC actuel, cela donne:

-Wabi -Wabi-tag -Waddress -Waggregate-return -Waggressive-loop-optimizations -Waliasing -Walign-commons -Wampersand -Warray-bounds -Warray-temporaries -Wassign-intercept -Wattributs -Wattributes -Wbad-function -Wbool-cast-compare -Wbuiltin-macro-redefined -Wc ++ - compat -Wc ++ 0x-compat -Wc ++ 14-compat -Wc-binding-type -Wc90-c99-compat -Wc99-c11-compat -Wcast-align -Wcast-qual -Wchar-subscripts -Wcharacter-truncation -Wchkp -Wclobbered -Wcomment -Wcompare-reals -Wconditional-supporté -Wconversion -Wconversion-extra -Wconversion-null -Wcoverage-mismatch -Wcpp -Wctor-privacy -after-statement -Wdelete-incomplet -Wdelete-non-virtuel-dtor -Wdeprecated -Wdeprecated-declarations -Wdesignated-init -Wdisabled-optimisation -Wdiscarded-tableau-qualificatifs -Wdiscarded-qualifiers -Wdivisé-de-zéro -W-double-promotion -Weffc ++ -Wempty-body -Wendif-labels -Wenum-compare -Wextra -Wfloat-égal -Wformat-contient-nul -Wformat-extra-args -Wformat-nonliteral -Wformat-security -Wformat-signedness - Wformat-y2k -Wformat-zero-length -Wfree-nonheap-object -Wfunction-élimination -Wignored-qualificateurs -Wimplicit -Wimplicit-déclaration-de-fonction -Wimplicit-int -Wimplicit-interface -Wimplicit-procedure -Wincompatible-pointer-types - Winherited-variadic-ctor -Winit-self -Winline -Wint-conversion -Wint-to-pointer-cast -Wintrinsic-shadow -Wintrinsics-std -Winvalid-memory-model -Winvalid-offset de -Winvalid-pch -Wjump-miss init -Wline-truncation -Wliteral-suffixe -Wlogical-not-parentheses -Wlogical-op -Wlong-long -Wmain -Wmaybe -uninitialized -Wmemset-transposed-args -Wmissing-braces -Wmissing-declarations -Wmissing-declarations -Wmissing-field-initializers - Wmissing-include-dirs -Wmissing-paramètre-type -Wmissing-prototypes -Wmultichar -Wnarrowing -Wnested-externs -Wnoexcept -Wnon-template-ami -Wnon-virtuel-dtor -Wnonnull -Wodr -Wold-style-casté -Wold- déclaration-de-style -Wold-style-definition -Wopenmp-simd -Woverflow -Woverlength-strings -Woverloaded-virtuel -Woverride-init -Wpacked -Wpacked-bitfield-compat -Wpadde d -Wparentheses -Wpedantic -Wpmf-conversions -Wpointer-arith -Wpointer-signe -Wpointer-in-int-cast -Wpragmas -Wprerty-assign-default -Wprotocol -Wreal-q-constant -Wrealloc-lhs -Wrealloc-lhs all -Wredundant-decls -Wreorder -Wreturn-local-addr -Wreturn-type -Wselector -Wsequence-point -Wshadow -Wshadow-ivar -Wshift-count-negative -Wshift-over-overflow -Wsign-compare -Wsign-promo Wsized-deallocation -Wsizeof-tableau-argument -Wsizeof-pointer-memaccess -Wstack-protector -Wstrict-null-sentinel -Wstrict-prototypes -Wstrict-selector-match -Wsuggest-attribut = const -Wsuggest-attribut = format -Wsuggest- attribut = noreturn -Wsuggest-attribut = pur -Wsuggest-méthodes-finales -Wsuggest-final-types -Wsuggest-override -Wsurprising -Wswitch -Wswitch-bool -Wswitch-default-types -Wsuggest-override headers -Wtabs -Wtarget-durée de vie -Wtraditional -Wtraditional-conversion -Wtrampolines -Wtrigraphs -Wtype-limits -Wundeclared-selector -Wundef -Wunderflow -Wuninitialized -Wunknown-pragmas -Wunknown-pragmas -Wuns optimisations de boucle - Constantes flottantes -Wunsuffixed -Wunused -Wunused-but-set-paramètre -Wunused-but-set-variable -Wunused-dummy-argument -Wunused-function -Wunused-set -Wunused-local-typedefedefs - Wunused-macros -Wunused-paramètre -Wunused-result -Wunused-value -Wunused-variable -Wuse-sans-seulement -Wuseless-cast -Wvarargs -Wvariadic-macros -Wvector-operation-performance -Wvirtual-move-assign-assign -Wvla - Wvolatile-register-var -Wwrite-strings -Wzero-as-null-pointeur-constant -Wzerotrip -frequire-return-statement

Ceci peut maintenant être utilisé pour appeler le GCC, c.-à-d.

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

Notez cependant que cela entraîne des avertissements car certaines options d’avertissement ne sont disponibles que dans certaines langues (par exemple, C++). Cela pourrait être évité en utilisant davantage de regex pour inclure uniquement les options autorisées pour la langue actuelle ou en ajoutant un -Wno-whatever Approprié à la fin de l'appel.

58
Haatschii

Il est tout simplement impossible de programmer avec tous les avertissements activés (à moins que vous ne les ignoriez, mais alors, pourquoi s'embêter?). Par exemple, supposons que vous utilisiez le jeu d’indicateurs suivant: -Wstrict-prototypes -Wtraditional.

Même avec deux avertissements activés, le programme suivant se plaindrait.

/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) {
     ^

Vous pouvez penser "bon, je vais utiliser des prototypes de style ancien alors". Non, ça ne marchera pas.

/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)
     ^

Et non, ne spécifier aucun prototype est également une erreur, car le compilateur se plaindra également.

/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() {
     ^

Si vous définissez des fonctions dans votre programme, vous ne pouvez pas utiliser tous les indicateurs, car le compilateur se plaindra de toute définition de fonction imaginable.

Pour C++, cela est possible (le -Wtraditional drapeau n'existe pas), et des programmes très simples peuvent être compilés. Pour activer tous les avertissements, utilisez la liste d’avertissements suivante (certains avertissements sont probablement dupliqués, car je ne me suis pas soucié de filtrer les avertissements activés par -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
15
Konrad Borowski

Une personne a créé un ensemble d’outils permettant de déterminer l’ensemble complet d’avertissements pour une version donnée de GCC ou de Clang.

Pour GCC, la copie de la liste complète des avertissements fournis par cet outil pour la version de votre compilateur semble être le moyen uniquement de vous assurer que tous les avertissements sont activés, car (contrairement à Clang), GCC ne fournit pas -Weverything.

L'outil semble analyser le c.opt dans le code source de GCC, ses résultats doivent être définitifs.

Le référentiel contient également des fichiers texte avec les listes d'avertissement générées pour la plupart des versions de GCC et Clang (actuellement Clang 3.2 à 3.7 et GCC 3.4 à 5.3).

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

5
Kyle Strand

Gcc 4.3+ a maintenant -Q --help = warnings, vous pouvez même spécifier --help = warnings, C pour simplement imprimer les avertissements liés à C.

Je viens d'écrire un module m4 pour tirer parti de cela (supporte également -Weverything de clang), voir wget_manywarnings.m4

Son utilisation est assez simple. En gros, le module active tous les avertissements. Et vous supprimez les avertissements si nécessaire - certains sont vraiment très prolixes. Exemple: configure.ac

Si vous n'utilisez pas autotools, vous trouverez le code pour activer tous les avertissements désactivés dans le module m4, qui correspond en gros à l'appel gcc acheminé via awk:

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

5
rockdaboot

Et je ne sais toujours pas si cette liste est exhaustive.

C'est probablement le cas, mais la seule liste exhaustive à 100% est la source réelle du compilateur. Cependant, GCC est gros! Et je ne sais pas si tous les paramètres de ligne de commande sont collectés à un endroit ou répartis sur plusieurs fichiers sources. Notez également que certains avertissements sont destinés au pré-processeur, certains au compilateur réel et certains à l'éditeur de liens (qui est un programme complètement séparé et se trouve dans le paquet binutils), de sorte qu'ils sont probablement dispersés.

3

De cette page :

Notez que certains drapeaux d’avertissement ne sont pas impliqués par -Wall. Certains mettent en garde contre des constructions que les utilisateurs ne considèrent généralement pas comme douteuses, mais que vous voudrez peut-être vérifier occasionnellement; d'autres avertissent des constructions nécessaires ou difficiles à éviter dans certains cas, et il n'existe aucun moyen simple de modifier le code pour supprimer l'avertissement. Certains d'entre eux sont activés par -Wextra mais beaucoup d’entre eux doivent être activés individuellement.

Je suppose que la question est lesquels ? Vous pourriez peut-être grep afficher cette page pour toutes les lignes commençant par -W et obtenir une liste complète des indicateurs d'avertissement. Ensuite, comparez-les avec les listes sous -Wall et -Wextra. Il y a aussi -Wpedantic, bien que vous souhaitiez évidemment être encore plus pédant = =

3
paddy