127 votes

Drapeaux pour activer les avertissements g++ détaillés et verbeux

Souvent en C sous gcc Je commencerai par l'ensemble des signaux d'alerte suivants (péniblement rassemblés à partir de sources multiples) :

-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

Je construis (au moins mes versions de débogage) avec cet ensemble d'avertissements et je corrige tout ce que je peux (généralement tout), puis je ne supprime les drapeaux que s'ils ne sont pas pertinents ou ne peuvent pas être corrigés (presque jamais le cas). Parfois, j'ajoute aussi -Werror si je dois m'absenter pendant la compilation.

Je viens de me mettre au C++ (oui, j'ai 15 ans de retard), et j'aimerais commencer du bon pied.

Ma question est la suivante : Quelqu'un dispose-t-il d'un ensemble similaire précompilé de drapeaux d'avertissement complets pour C++ sous g++ ? (Je sais que beaucoup d'entre eux seront les mêmes).

78 votes

Ce dont gcc a besoin (depuis qu'il a décidé de flageller mentir sobre -Wall ) est un -Wbloody_everything drapeau :-)

0 votes

Vous pouvez marquer votre question comme un doublon mais vous pouvez aussi mettre votre dernière modification comme une réponse puisque vous avez effectivement répondu à votre question. Et je serais heureux de l'upvoter dans ce cas :)

0 votes

Oh, bonne idée ! Je ne peux pas accepter avant deux jours, mais peut-être que quelqu'un d'autre proposera des drapeaux supplémentaires entre-temps.

149voto

David Stone Points 3822

J'ai parcouru et trouvé l'ensemble minimal d'inclusions qui devraient obtenir le niveau maximal d'avertissement. J'ai ensuite supprimé de cette liste l'ensemble des avertissements qui, à mon avis, n'indiquent pas réellement que quelque chose de mauvais se passe, ou qui ont trop de faux positifs pour être utilisés dans une construction réelle. J'ai expliqué pourquoi chacun des avertissements que j'ai exclus l'a été. Voici ma liste finale d'avertissements suggérés :

-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

Les avertissements douteux qui sont présents :

  • J'inclus -Wno-unused parce que j'ai souvent des variables que je sais que je que je vais utiliser plus tard, mais pour lesquelles je n'ai pas encore écrit la fonctionnalité. Supprimer les avertissements à ce sujet me permet d'écrire dans mon style préféré de différer occasionnellement l'implémentation de certaines choses. Il est utile de désactiver cette fonction de temps en temps pour s'assurer que rien ne s'est glissé à travers les mailles du filet.

  • -Wdisabled-optimization semble être une préférence forte de l'utilisateur de l'utilisateur. Je viens d'ajouter celui-ci à mon build (uniquement pour les builds optimisés pour des raisons évidentes) et il n'a rien fait apparaître, donc il ne semble pas que ce soit un avertissement particulièrement bavard. ne semble pas être un avertissement particulièrement bavard, du moins pour la façon dont je code. Je l'inclus (même si le code qui déclenche cet avertissement n'est pas nécessairement mauvais) parce que je crois que le code qui déclenche cet avertissement n'est pas nécessairement mauvais. n'est pas nécessairement mauvais) parce que je crois qu'il faut travailler avec mes outils plutôt que contre eux. Si gcc me dit qu'il ne peut pas optimiser le code pour la façon dont je l'ai écrit, alors je devrais envisager de le réécrire. Je soupçonne Je soupçonne que le code qui déclenche cet avertissement pourrait bénéficier d'être plus modulaire, quoi qu'il en soit, donc même si le code n'est pas techniquement mauvais (probablement), stylistiquement il n'est pas bon. (probablement), stylistiquement il l'est probablement.

  • -Wfloat-equal prévient pour des comparaisons d'égalité sûres (en particulier, comparaison avec une valeur non calculée de -1). Un exemple dans mon code où j'utilise ceci est que j'ai un vecteur de float. Je parcours ce vecteur, et il y a quelques éléments que je ne peux pas encore évaluer ce qu'ils donc je leur attribue la valeur -1.0f (puisque mon problème n'utilise que la fonction positifs, -1 est hors du domaine). Plus tard, je passe en revue et mettre à jour les valeurs -1.0f. Ce problème ne se prête pas facilement à une autre méthode d'opération différente. Je pense que la plupart des gens n'ont pas ce problème. problème, et la comparaison d'un nombre exact en virgule flottante est probablement une erreur. probablement une erreur, donc je l'inclus dans la liste par défaut.

  • -Wold-style-cast a beaucoup de faux positifs dans le code de la bibliothèque que j'utilise. En particulier, la famille de fonctions htonl utilisée en réseau, ainsi qu'une implémentation de cryptage Rijndael (AES) que j'utilise, ont des castings de style ancien dont il me prévient. J'ai l'intention de remplacer ces deux fonctions, mais je ne suis pas sûr qu'il y ait autre chose dans mon code dont il se plaindra. La plupart des utilisateurs devraient probablement l'activer par défaut, cependant.

  • -Wsign-conversion a été difficile (et a failli ne pas être retenu). liste). L'activer dans mon code générait une quantité énorme d'avertissements (100+). Presque tous étaient innocents. Cependant, j'ai été prudent d'utiliser des entiers signés chaque fois que je n'étais pas sûr, bien que pour pour mon domaine particulier, j'obtiendrais généralement une légère augmentation d'efficacité en utilisant des valeurs non signées en raison de la grande quantité de division d'entiers que je fais. division d'entiers que je fais. J'ai sacrifié cette efficacité parce que je craignais de promouvoir accidentellement un entier signé en un entier non signé, puis de le diviser (ce qui n'est pas sûr). diviser (ce qui n'est pas sans danger, contrairement à l'addition, la soustraction et la multiplication). L'activation de cet avertissement m'a permis de modifier en toute sécurité la plupart de mes variables en types non signés et d'ajouter quelques casts dans certaines autres endroits. C'est actuellement un peu difficile à utiliser parce que l'avertissement n'est pas si intelligent. Par exemple, si vous faites unsigned short + (integral constant expression) ce résultat est implicitement promu en int. Le site vous avertit ensuite d'un problème de signe potentiel si vous affectez cette valeur à la variable unsigned o unsigned short même si c'est sans danger. C'est certainement l'avertissement le plus facultatif pour presque tous les utilisateurs.

  • -Wsign-promo : voir -Wsign-conversion .

  • -Wswitch-default semble inutile (vous ne voulez pas toujours une valeur par défaut si vous avez énuméré toutes les possibilités explicitement). Cependant, l'activation de cet avertissement peut imposer quelque chose qui est probablement une bonne idée. Pour les cas où vous voulez explicitement ignorer tout sauf les possibilités énumérées (mais d'autres nombres sont possibles), mettez alors dans default: break; pour le rendre explicite. Si l'on énumère explicitement toutes les possibilités, alors l'activation de cet avertissement aidera à garantir que vous mettez quelque chose comme assert (false) pour vous assurer que vous avez effectivement couvert toutes les options possibles. Cela vous permet d'être explicite dans le domaine de votre problème et de le faire respecter par le programme. Cependant, vous devrez être prudent en collant assert (false) partout. C'est mieux que de ne rien faire avec le cas par défaut, mais mais, comme d'habitude avec assert, cela ne fonctionnera pas dans les versions publiées. En d'autres termes En d'autres termes, vous ne pouvez pas compter sur lui pour valider les nombres que vous obtenez de, d'une connexion réseau ou d'une base de données dont vous n'avez pas le contrôle absolu. absolu. Les exceptions ou les retours anticipés sont la meilleure façon de de gérer ce genre de situation (mais il faut tout de même prévoir un cas par défaut !)

  • -Werror est un élément important pour moi. Lorsque l'on compile de grandes quantités de code dans une compilation multi-thread avec de multiples cibles, il est facile pour un facile de passer à côté d'un avertissement. Transformer les avertissements en erreurs garantit que je les les remarque.

Il y a ensuite un ensemble d'avertissements qui ne sont pas inclus dans la liste ci-dessus parce que je ne les ai pas trouvés utiles. Voici les avertissements et mes commentaires sur les raisons pour lesquelles je ne les inclus pas dans la liste par défaut :

Les avertissements qui sont absents :

  • -Wabi n'est pas nécessaire car je ne combine pas des binaires provenant de compilateurs différents. J'ai quand même essayé de compiler avec, et cela ne s'est pas déclenché, donc cela ne semble pas inutilement verbeux.

  • -Waggregate-return n'est pas quelque chose que je considère comme une erreur. Pour par exemple, elle se déclenche lors de l'utilisation d'une boucle for basée sur l'intervalle sur un vecteur de classes. L'optimisation des valeurs de retour devrait permettre d'éviter effets négatifs de ce phénomène.

  • -Wconversion déclencheurs sur ce code : short n = 0; n += 2; Le site La conversion implicite en int provoque un avertissement lorsqu'elle est ensuite convertie dans son type cible.

  • -Weffc++ inclut un avertissement si tous les membres de données ne sont pas initialisés dans la liste des initialisateurs. Je ne le fais pas intentionnellement dans de nombreux cas, de sorte que l'ensemble des avertissements est trop encombré pour être utile. Il est utile de l'activer de temps en temps et de rechercher d'autres avertissements, cependant (comme les destructeurs non virtuels des classes de base). Ceci serait plus utile comme une collection d'avertissements (comme les -Wall ) au lieu de un seul avertissement en soi.

  • -Winline est absent parce que je n'utilise pas le mot clé inline pour d'optimisation, juste pour définir des fonctions en ligne dans les en-têtes. I Je ne me préoccupe pas de savoir si l'optimiseur les met effectivement en ligne. Cet avertissement est également se plaint également s'il ne peut pas mettre en ligne une fonction déclarée dans le corps d'une classe (par exemple, un destructeur virtuel vide). (comme un destructeur virtuel vide).

  • -Winvalid-pch est manquant parce que je n'utilise pas d'en-têtes précompilés.

  • -Wmissing-format-attribute n'est pas utilisé car je n'utilise pas gnu les extensions. Idem pour -Wsuggest-attribute et plusieurs autres

  • L'absence de l'un d'entre eux est potentiellement remarquable. -Wno-long-long dont je n'ai dont je n'ai pas besoin. Je compile avec -std=c++0x ( -std=c++11 dans GCC 4.7), qui comprend long long les types d'entiers. Ceux qui sont bloqués sur C++98 / C++03 peuvent envisager d'ajouter cette exclusion à la liste des avertissements.

  • -Wnormalized=nfc est déjà l'option par défaut, et semble être la meilleure.

  • -Wpadded est activé de temps en temps pour optimiser la disposition des classes, mais elle n'est pas activée car toutes les classes n'ont pas assez d'éléments d'éléments pour supprimer le padding à la fin. En théorie, je pourrais obtenir quelques variables supplémentaires gratuitement, mais cela ne vaut pas la peine de faire l'effort supplémentaire de maintenir (si la taille de ma classe change, il n'est pas facile de supprimer ces supprimer les variables précédemment gratuites).

  • -Wstack-protector n'est pas utilisé car je n'utilise pas -fstack-protector

  • -Wstrict-aliasing=3 est activé par -Wall et est le plus précis, mais il semble que les niveaux 1 et 2 donnent plus d'avertissements. Sur En théorie, un niveau inférieur est un avertissement "plus fort", mais c'est au prix de plus de faux positifs. plus de faux positifs. Mon propre code de test a compilé proprement sous les 3 niveaux. niveaux.

  • -Wswitch-enum n'est pas un comportement que je veux. Je ne veux pas gérer chaque instruction switch de manière explicite. Il serait utile que le langage disposait d'un mécanisme permettant d'activer cette fonction sur des instructions switch spécifiques. (pour s'assurer que les futures modifications de l'enum sont traitées partout où elles qu'elles doivent l'être), mais c'est un peu exagéré pour un réglage "tout ou rien". tout ou rien.

  • -Wunsafe-loop-optimizations provoque trop d'avertissements intempestifs. Il peut être utile d'appliquer celui-ci périodiquement et de vérifier manuellement les résultats. A titre d'exemple, elle a généré cet avertissement dans mon code lorsque je bouclais sur tous les éléments d'un vecteur pour leur appliquer un ensemble de fonctions (en utilisant la boucle for basée sur la plage). fonctions (en utilisant la boucle for basée sur la plage). Il émet également un avertissement pour le constructeur d'un tableau const de const std::string (où il n'y a pas de boucle dans le code utilisateur).

  • -Wzero-as-null-pointer-constant y -Wuseless-cast sont avertissements réservés à GCC-4.7, que j'ajouterai lorsque je passerai à GCC 4.7.

J'ai déposé quelques rapports de bogue / demandes d'amélioration à gcc suite à certaines de ces recherches, donc j'espère pouvoir éventuellement ajouter plus d'avertissements de la liste "do not include" à la liste "include". Cette liste comprend tous les avertissements mentionnés dans ce fil de discussion (plus quelques autres, je pense). La plupart des avertissements qui ne sont pas explicitement mentionnés dans ce message sont inclus dans un autre avertissement que je mentionne. Si quelqu'un remarque des avertissements qui sont entièrement exclus de ce message, faites-le moi savoir.

éditer : Il semble que j'en ai oublié plusieurs (que j'ai maintenant ajoutés). Il y a en fait une deuxième page à http://gcc.gnu.org qui est assez bien caché. Options d'alerte générale y Options C++ (faites défiler jusqu'en bas pour les avertissements)

41voto

Sdaz MacSkibbons Points 6982

D'oh, toutes mes recherches initiales ont abouti à 99% de messages sur la façon de supprimer des avertissements (assez effrayant), mais je viens de tomber sur ce commentaire qui présente cette belle série de drapeaux (certains moins pertinents) :

Cross a vérifié avec :

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

Donc, je pense que c'est un bon point de départ. Je n'avais pas réalisé que c'était un double, mais au moins c'était profondément enterré. :-)

1 votes

Peut-être, mais cela semble changer d'une version à l'autre, et probablement au gré des taches solaires et de RMS, donc être trop explicite ne fera probablement pas de mal. C'est un bon point de départ, de toute façon.

3 votes

D'après une recherche rapide de 'case OPT_W' dans c-opts.c/opts.c de la version 4.5.2, il manque : strict overflow, undef, strict nul sentinel, normalized, multichar, implicit function declaration, deprecated, endif labels, comment s , macro intégrée redéfinie, plus grand que, plus grand que eq, abi. C'est fou qu'il n'y ait pas une option de ligne de commande pour les lister.

3 votes

Je pense que c'est plus fou que -Wall ne fait pas ce que l'on attend d'elle. Mais merci, certains de ces éléments semblent très utiles !

14voto

Let_Me_Be Points 16797

Certaines d'entre elles sont déjà incluses dans -Wall o -Wextra .

Une bonne configuration de base pour C est :

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

et pour C++

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

(en sautant -Werror pour C++ depuis -Weffc++ a quelques inconvénients)

11 votes

-Werror peut être désactivé pour des types d'avertissements spécifiques, par exemple : -Werror -Weffc++ -Wno-error=effc++.

2 votes

ansi : En mode C, ceci est équivalent à -std=c89 . En mode C++, il est équivalent à -std=c++98 . c'est-à-dire que si vous spécifiez une autre std ne pas utiliser ansi

2voto

Essayez

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

C'est un moyen rapide et sale de démarrage qui sera certainement besoin de quelques réglages; pour une chose, même si vous appelez le compilateur par le nom approprié pour votre langue (par exemple, g++ pour le C++), vous obtiendrez les mises en garde qui ne s'appliquent pas à cette langue (et le compilateur va jeter ses mains et refuser de continuer jusqu'à ce que vous supprimer l'avertissement).

Une autre chose est que j'ai ajouté dans -Werror, parce que si vous n'êtes pas, fixant les avertissements, pourquoi vous préoccupez-vous de les allumer? Vous pouvez également prendre des avertissements de la liste (Par exemple, je n'ai presque jamais utiliser -Waggregate-return avec le C++).

Quelques mises en garde ne sont rien sans les autres liées à la performance des options (-Wstack-protector). -fdiagnostic-show-option et le manuel de GCC sont vos amis.

BTW, certains avertissements sont mutuellement exclusives; en particulier à l'aide de -Wtraditional et -Wold-style-definition avec -Werror, ne compilera pas.

0voto

snr Points 4881

Dans le CmakeLists.txt de mon Clion

cmake_minimum_required(VERSION 3.13)
project(cpp17)

set(CMAKE_CXX_STANDARD 17)

set(GCC_COVERAGE_COMPILE_FLAGS "-std=c++17 -Wall -Weffc++ -Wno-error=effc++ -pedantic \
 -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-newline-eof  \
-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")

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}" )

add_executable(cpp17 main.cpp)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X