En tant que programmeur C & Objective-C, je suis un peu paranoïaque avec les drapeaux d'avertissement du compilateur.
J'essaie généralement de trouver une liste complète de drapeaux d'avertissement pour le compilateur que j'utilise et d'activer la plupart d'entre eux, sauf si j'ai une très bonne raison de ne pas l'activer.
Personnellement, je pense que cela peut réellement améliorer les compétences de codage, ainsi que la portabilité potentielle du code, éviter certains problèmes, car cela vous oblige à prendre conscience de chaque détail, de problèmes potentiels de mise en œuvre et d'architecture, etc.
C'est aussi à mon avis un bon outil d'apprentissage au quotidien, même si vous êtes un programmeur expérimenté.
Pour la partie subjective de cette question, je voudrais entendre d’autres développeurs (principalement C, Objective-C et C ++) sur ce sujet.
Vous souciez-vous réellement de choses comme des avertissements pédantiques, etc.? Et si oui ou non, pourquoi?
Maintenant, à propos d’Objective-C, je suis récemment passé complètement à la chaîne d’outils LLVM (avec Clang), au lieu de GCC.
Sur mon code de production, je règle habituellement ces drapeaux d'avertissement (explicitement, même si certains d'entre eux peuvent être couverts par -Wall):
- -Mur
- -Wbad-function-cast
- -Wcast-align
- -Conversion
- -Wdeclaration-after-statement
- -Wdeprecated-implémentations
- -Wextra
- -Wfloat-égal
- -Wformat = 2
- -Wformat-nonliteral
- -Quatre-constantes-char
- -Wimplicit-atomic-properties
- -Accessoires-manquants
- -Missions déclarées
- -Initialiseurs de champs manquants
- Attribut de format -Wmissing
- -Voulant-noreturn
- Prototypes manquants
- -Wnested-externs
- -Wnewline-eof
- -Wold-style-definition
- -Woverlength-strings
- -Parenthèses
- -Wpointer-arith
- -Wredundant-decls
- Type de retour
- -Point de séquence
- -Ours
- -Wshorten-64-à-32
- -Signature-comparer
- -Signature-conversion
- -Protection-prototypes
- -Wstrict-selector-match
- -Wswitch
- -Wswitch-default
- -Wswitch-enum
- Sélecteur de lunette
- -Wuninitialisé
- Pragmas méconnus
- -Le code inaccessible
- -Fonction non utilisée
- -Etiquette non utilisée
- Paramètre non utilisé
- -Wunused-value
- -Variable non utilisée
- -Write-strings
Je suis intéressé à entendre ce que les autres développeurs ont à dire à ce sujet.
Par exemple, pensez-vous que j'ai raté un drapeau particulier pour Clang (Objective-C) et pourquoi?
Ou pensez-vous qu'un drapeau particulier n'est pas utile (ou pas du tout voulu), et pourquoi?
MODIFIER
Pour clarifier la question, notez que -Wall
ne fournit que quelques avertissements de base.
Ce sont en réalité beaucoup plus de drapeaux d'avertissement, non couverts par -Wall
, d'où la question et la liste que je fournis.
la source
-Wwrite-strings
cela en fait un compilateur d’un langage très similaire mais pas tout à fait C. Pour cette seule raison, je n’utilise pas cette option. Autres que ceux que vous spécifiez, j'utilise-pedantic -Wstrict-overflow=5 -Winline -Wundef -Wcast-qual -Wlogical-op -Wstrict-aliasing=2
et-Wno-missing-braces -Wno-missing-field-initializers
pour l'initialiseur parfaitement raisonnablestruct whatever obj = {0};
. Aussi, je trouve que cela-Wconversion
donne plus de "spam" que d’avertissements utiles :)Réponses:
Pour le contexte, je suis un développeur Clang travaillant chez Google. Chez Google, nous avons étendu les diagnostics de Clang à (essentiellement) tous nos développeurs C ++, et nous traitons également les avertissements de Clang comme des erreurs. En tant que développeur Clang et l'un des principaux utilisateurs des diagnostics de Clang, je vais essayer de faire la lumière sur ces indicateurs et sur la manière dont ils peuvent être utilisés. Notez que tout ce que je décris est génériquement applicable à Clang, et non spécifique à C, C ++ ou Objective-C.
TL; DR Version: Veuillez utiliser
-Wall
et-Werror
au minimum tout nouveau code que vous développez. Nous (les développeurs du compilateur) ajoutons ici des avertissements pour de bonnes raisons: ils trouvent des bogues. Si vous trouvez un avertissement qui attrape des bugs pour vous, activez-le également. Essayez d'-Wextra
avoir un groupe de bons candidats ici. Si l’un d’eux est trop bruyant pour que vous l’utilisiez de manière rentable, signalez un bogue . Si vous écrivez du code contenant un bogue "évident" mais que le compilateur ne vous en a pas averti, créez un bogue.Maintenant pour la version longue. Tout d'abord quelques informations sur les groupes d'indicateurs d'avertissement. Il y a beaucoup de "groupements" d'avertissements dans Clang (et dans une moindre mesure dans GCC). Certains qui sont pertinents pour cette discussion:
-Wall
: Ce sont des avertissements que les développeurs ont une grande confiance dans leur valeur et un faible taux de faux positifs.-Wextra
: Ce sont des avertissements qui sont considérés comme précieux et valables (c’est-à-dire qu’ils ne sont pas buggés), mais ils peuvent présenter des taux de faux positifs élevés ou des objections philosophiques communes.-Weverything
: Ceci est un groupe insensé qui active littéralement tous les avertissements dans Clang. Ne l'utilisez pas dans votre code. Il est destiné uniquement aux développeurs Clang ou à l'exploration des avertissements existants .Il existe deux critères principaux mentionnés ci-dessus qui guident les avertissements dans Clang, et clarifions leur signification. Le premier est la valeur potentielle d'une occurrence particulière de l'avertissement. C'est l'avantage attendu par l'utilisateur (développeur) lorsque l'avertissement se déclenche et qui identifie correctement un problème avec le code.
Le deuxième critère est l’idée de déclarations faussement positives . Ce sont des situations où l'avertissement se déclenche sur le code, mais le problème potentiel évoqué ne se produit en fait pas à cause du contexte ou d'une autre contrainte du programme. Le code sur lequel on vous a prévenu se comporte correctement. Celles-ci sont particulièrement dommageables lorsque l'avertissement n'a jamais été conçu pour déclencher ce code. Au lieu de cela, c'est une déficience dans la mise en œuvre de l'alerte qui la déclenche là.
Pour les avertissements Clang, la valeur doit être exprimée en termes d' exactitude , et non en termes de style, de goût ou de conventions de codage. Cela limite l'ensemble des avertissements disponibles, en excluant les avertissements souvent demandés tels que les avertissements lorsque
{}
aucun s n'est utilisé autour du corps d'uneif
instruction. Clang est également très intolérant envers les faux positifs . Contrairement à la plupart des autres compilateurs, il utilisera une incroyable variété de sources d’information pour élaguer les faux positifs, notamment l’orthographe exacte de la construction, la présence ou non de macros «()» supplémentaires, ou même de préprocesseurs!Prenons maintenant des exemples concrets d’avertissements de Clang et examinons leur classement. Tout d'abord, un avertissement par défaut:
Ici, aucun drapeau n'était requis pour obtenir cet avertissement. La raison en est que ce code n’est jamais vraiment correct, ce qui donne une valeur élevée à l’avertissement , et cet avertissement ne déclenche que le code que Clang peut prouver tombe dans ce compartiment, ce qui lui donne un taux de zéro faux positif .
Clang requiert le
-Wall
drapeau pour cet avertissement. La raison en est qu’il existe une quantité non négligeable de code qui a utilisé (pour le meilleur ou pour le pire) le modèle de code sur lequel nous avertissons de produire intentionnellement une valeur non initialisée. Philosophiquement, je ne vois pas l'intérêt de cela, mais beaucoup d'autres sont en désaccord et la réalité de cette divergence d'opinion est ce qui motive l'avertissement sous le-Wall
drapeau. Il a toujours une valeur très élevée et un taux de faux positifs très bas , mais sur certains codes, il est non partant.Cet avertissement nécessite le
-Wextra
drapeau. La raison en est qu’il existe de très grandes bases de code où les comparaisons de signatures mal appariées sont extrêmement courantes. Bien que cet avertissement trouve des bogues, la probabilité que le code soit un bogue lorsque l'utilisateur l'écrit est en moyenne assez faible. Le résultat est un taux extrêmement élevé de faux positifs . Cependant, lorsqu'un programme contient un bogue en raison d'étranges règles de promotion, il est souvent extrêmement subtil de rendre cet avertissement lorsqu'il signale qu'un bogue a une valeur relativement élevée . En conséquence, Clang le fournit et l’expose sous un drapeau.Généralement, les avertissements ne survivent pas longtemps en dehors du
-Wextra
drapeau. Clang essaie très fort de ne pas mettre en œuvre des avertissements qui ne sont pas régulièrement utilisés et testés. Les avertissements supplémentaires activés par-Weverything
sont généralement des avertissements en développement actif ou avec des bogues actifs. Soit ils seront fixés et placés sous des drapeaux appropriés, soit ils devraient être supprimés.Maintenant que nous comprenons comment ces choses fonctionnent avec Clang, essayons de revenir à la question initiale: quels avertissements devriez-vous activer pour votre développement? La réponse est, malheureusement, que cela dépend. Réfléchissez aux questions suivantes pour déterminer les avertissements les mieux adaptés à votre situation.
Tout d'abord, si vous ne contrôlez pas le code, n'essayez pas d'activer des avertissements supplémentaires. Préparez-vous à en éteindre. Il y a beaucoup de mauvais codes dans le monde, et vous ne pourrez peut-être pas tout réparer. C'est bon. Travaillez pour trouver un moyen de concentrer vos efforts sur le code que vous contrôlez.
Ensuite, déterminez ce que vous voulez sortir de vos avertissements. Ceci est différent pour différentes personnes. Clang essaiera d’avertir sans aucune option pour les bogues évidents ou les modèles de code pour lesquels nous avons un précédent historique qui indique que le taux de bogues est extrêmement élevé. En activant cette fonctionnalité,
-Wall
vous obtiendrez un ensemble d'avertissements beaucoup plus agressif visant à détecter les erreurs les plus courantes observées par les développeurs Clang dans le code C ++. Mais avec ces deux facteurs, le taux de faux positifs devrait rester assez faible.Enfin, si vous êtes parfaitement disposé à faire taire les * faux-positifs * à chaque tour, foncez
-Wextra
. Si vous remarquez des avertissements qui attirent de nombreux bogues réels, mais qui ont des faux positifs stupides ou inutiles, vous pouvez créer des bogues. Nous travaillons constamment pour trouver des moyens d'introduire de plus en plus de la logique de recherche de bogues-Wextra
dans-Wall
laquelle nous pouvons éviter les faux positifs.Beaucoup trouveront qu'aucune de ces options n'est juste pour eux. Chez Google, certains avertissements ont été
-Wall
désactivés, car de nombreux codes existants ne respectaient pas cet avertissement. Nous avons également activé explicitement certains avertissements, même s'ils ne sont pas activés par-Wall
, car ils ont une valeur particulièrement élevée pour nous. Votre kilométrage variera, mais variera probablement de la même manière. Il peut souvent être préférable d’activer quelques avertissements clés plutôt que tous-Wextra
.J'encourage tout le monde à activer le
-Wall
code non hérité. Pour les nouveaux codes, les avertissements ici sont presque toujours précieux et améliorent réellement l'expérience de développement de code. Inversement, j'encourage tout le monde à ne pas autoriser les drapeaux au-delà-Wextra
. Si vous trouvez un avertissement de Clang qui-Wextra
ne comprend pas , mais qui prouve tout précieux pour vous, déposer simplement un bug et nous pouvons probablement le mettre sous-Wextra
. Que vous activiez explicitement un sous-ensemble des avertissements dans-Wextra
dépendra beaucoup de votre code, de votre style de codage et de la pertinence de la gestion de cette liste plutôt que de tout réparer-Wextra
.Parmi la liste d'avertissements de l'OP (qui incluait les deux
-Wall
et-Wextra
), seuls les avertissements suivants ne sont pas couverts par ces deux groupes (ou activés par défaut). Le premier groupe explique pourquoi le recours excessif à des indicateurs d'avertissement explicites peut être mauvais: aucun de ceux-ci n'est même implémenté dans Clang! Ils sont acceptés sur la ligne de commande uniquement pour la compatibilité GCC.-Wbad-function-cast
-Wdeclaration-after-statement
-Wmissing-format-attribute
-Wmissing-noreturn
-Wnested-externs
-Wnewline-eof
-Wold-style-definition
-Wredundant-decls
-Wsequence-point
-Wstrict-prototypes
-Wswitch-default
Les prochains avertissements inutiles dans la liste d'origine sont ceux qui sont redondants avec ceux de cette liste:
-Wformat-nonliteral
-- Sous-ensemble de-Wformat=2
-Wshorten-64-to-32
-- Sous-ensemble de-Wconversion
-Wsign-conversion
-- Sous-ensemble de-Wconversion
Il existe également une sélection d'avertissements plus catégoriquement différents. Celles-ci traitent de variantes linguistiques du dialecte plutôt que de codes bogués ou non bogués. À l'exception de
-Wwrite-strings
, tous ces avertissements concernent les extensions de langage fournies par Clang. Que Clang avertisse de leur utilisation dépend de la prévalence de l'extension. Clang vise la compatibilité GCC et, dans de nombreux cas, simplifie ainsi la tâche avec des extensions de langage implicites largement utilisées.-Wwrite-strings
, comme indiqué dans l'OP, est un indicateur de compatibilité de GCC qui modifie réellement la sémantique du programme. Je regrette profondément ce drapeau, mais nous devons le soutenir en raison de l'héritage qu'il a aujourd'hui.-Wfour-char-constants
-Wpointer-arith
-Wwrite-strings
Les options restantes permettant des avertissements potentiellement intéressants sont les suivantes:
-Wcast-align
-Wconversion
-Wfloat-equal
-Wformat=2
-Wimplicit-atomic-properties
-Wmissing-declarations
-Wmissing-prototypes
-Woverlength-strings
-Wshadow
-Wstrict-selector-match
-Wundeclared-selector
-Wunreachable-code
La raison pour laquelle ils ne sont pas
-Wall
ou-Wextra
ne sont pas toujours clairs. Pour beaucoup d' entre eux, ils sont en fait basés sur les avertissements du CCG (-Wconversion
,-Wshadow
, etc.) et en tant que telle Clang tente d'imiter le comportement de GCC. Nous en décomposons progressivement certaines en des mises en garde plus fines et utiles. Ceux-ci ont alors une probabilité plus élevée de faire partie de l’un des groupes d’alerte les plus avancés. Cela dit, choisir un seul avertissement-Wconversion
est si vaste qu'il restera probablement sa propre catégorie de "premier niveau" dans un avenir prévisible. Certains autres avertissements dont dispose GCC mais qui ont une faible valeur et des taux de faux positifs élevés peuvent être relégués au rang de no man's land.Parmi les autres raisons pour lesquelles ils ne font pas partie des plus grands compartiments, citons les bogues simples, les très importants problèmes de faux positifs et les avertissements en cours de développement. Je vais examiner le classement des bogues pour ceux que je peux identifier. Ils devraient tous éventuellement migrer vers un grand drapeau de seau approprié ou être retirés de Clang.
J'espère que cela clarifie la situation d'avertissement avec Clang et fournit quelques informations à ceux qui essaient de choisir un ensemble d'avertissements pour leur utilisation ou l'utilisation de leur entreprise.
la source
-Wno
à éteindrewarn_no_constructor_for_refconst
rend PITA utiliser Boost.ConceptCheck et similaires: github.com/boostorg/concept_check/blob/…Je n'utilise pas Clang, mais j'espère que mon opinion ne me dérange pas. J'utilise également le niveau d'avertissement maximal (je suppose que c'est ce que signifie -Wall) et de traiter les avertissements comme des erreurs (je suppose que c'est ce que signifie -Werror) et je ne désactive que les quelques avertissements qui n'ont pas beaucoup de sens. En fait, le fait que certains avertissements très utiles ne soient pas émis par le compilateur C # me contrarie énormément, et il est nécessaire d’exécuter des outils spéciaux d’analyse de code pour les visualiser. J'aime les avertissements, car ils m'aident à attraper de petites erreurs et des bugs dans mon code. Je les aime tellement que lorsqu'un avertissement est émis pour un élément de code que je sais être correct, je le reformule quand même de sorte que l'avertissement ne soit pas émis, plutôt que de le désactiver, ou - même pire, laissez-le apparaître et ignorez-le. Je pense que les avertissements sont géniaux,
la source
-Wall
ne fournit que des avertissements de base. Beaucoup de drapeaux d'avertissement existants ne sont pas couverts-Wall
, d'où la liste dans ma question.Je vais généralement avec les paramètres par défaut de Xcode pour un nouveau projet; il fournit un bon équilibre entre utile et ennuyeux. Toute liste spécifique d’avertissements et d’autres options du compilateur reposera en grande partie sur les préférences personnelles ou sur les exigences du projet. Je ne pense donc pas qu’il soit très utile d’essayer de parcourir votre liste et de plaider pour ou contre des avertissements spécifiques. Si cela fonctionne pour vous, tant mieux. Si vous trouvez que vous avez commis une erreur que le compilateur devrait pouvoir détecter et que vous souhaitez obtenir de l'aide à ce sujet à l'avenir, recherchez une option du compilateur pour vous en avertir et activez-la.
Certains programmeurs préconisent d'activer l'option "Traiter les avertissements comme des erreurs" (-Werror) pour empêcher les générations de se terminer avec succès s'il y avait des avertissements.
la source
-Werror
. En fait, comme j'utilise Clang, je mets tous ces avertissements en utilisant pragma (#pragma tintement de diagnostic), et ils sont mis à des erreurs fatales, c'est donc le même que-Werror
:)Je pense que la meilleure preuve que les gens se soucient des avertissements est le fait qu'ils existent et sont largement utilisés. Je suis fermement convaincu que plus il y a d'erreurs détectées pendant la compilation, mieux c'est. Si cette croyance n'était pas largement répandue, tout le monde utiliserait des langages faiblement typés de manière dynamique, car leurs compilateurs ou interprètes vous donnent beaucoup plus de latitude. Au contraire, même sur les langages de script, l’utilisation des
strict
drapeaux est populaire. Sur les langages statiques fortement typés, non seulement les gens utilisent-Wall -Werror
fréquemment, mais ils trouvent souvent les avertissements si précieux qu'ils en veulent encore plus , et paient donc pour des outils d'analyse statiques tels que Coverity, dont le seul but est de fournir des avertissements.Cela ne signifie pas qu'il n'y a pas de détracteurs. Un grand nombre de développeurs considèrent que les avertissements vont à l’encontre de ceux-ci à court terme plutôt que de les défendre à long terme, et n’essaient pas de résoudre le problème sous-jacent. Par conséquent, vous voyez un code charmant comme ce bout de code que j'ai rencontré hier:
la source
-Werror
et ignorer les avertissements émis par le compilateur. Ou s'ils le font, ils s'en tiennent généralement à-Wall
. La plupart des drapeaux que je fournis dans ma question ne sont pas couverts-Wall
et je pense personnellement qu'ils sont également essentiels. Alors je suis juste paranoïaque? ; )En règle générale, je me penche davantage vers -Wall et je crois vraiment y compris -Werror. Un module n'aurait jamais dû s'attendre à des avertissements. Vous finirez par recevoir un autre avertissement et le rater. Et ce sera celui qui pose problème.
Cela dépend également de l'ajout de "-Wall -Werror" à un nouveau ou à un ancien projet. Si c'est nouveau, allez-y et exigez la perfection, sinon vous risquez probablement des jours ou des semaines de modifications et de tests. Je viens de faire cela sur un projet plus ancien et un peu petit et j'ai passé deux ou trois jours à supprimer les avertissements. Je pense que le code est plus propre maintenant.
En d'autres termes, essayez et voyez.
Excité
la source
-Wall
et-Werror
, je suppose que vous devriez relire la question. Beaucoup de drapeaux d'avertissement ne sont pas couverts par-Wall
. Merci pour la réponse, de toute façon.