Pourquoi devrait-on vouloir désactiver les avertissements du compilateur?

26

Cette réponse et les commentaires qui y sont ajoutés montrent un moyen de désactiver plusieurs avertissements du compilateur à l'aide de #pragmadirectives.

Pourquoi voudrait-on faire ça? Habituellement, les avertissements sont là pour une raison, et j'ai toujours pensé que ce sont de bonnes raisons. Existe-t-il un "cas valide" où les avertissements devraient être désactivés? Pour le moment, je ne pense à aucun, mais c'est peut-être juste moi.

takrl
la source
4
Je ne sais pas pourquoi quelqu'un l'a marqué pour fermer. Cela me semble être une question éminemment raisonnable. +1
@Alastair Pitts: J'ai proposé une migration vers les programmeurs. J'ai réalisé mon erreur plus tard.
Tugrul Ates
3
Les messages d'avertissement sont là pour une raison, oui, mais il y a aussi une raison pour laquelle ce ne sont pas des messages d' erreur .
Solomon Slow
2
@jameslarge Votre commentaire résume bien la situation. Un avertissement est le compilateur vous indiquant qu'une situation est plausiblement mauvaise , ce qui implique peut-être juste . Si c'était définitivement faux, ce serait une erreur. Étant donné que certains avertissements peuvent être de faux positifs, il doit toujours y avoir un moyen d'écrire du code de manière à éliminer l'avertissement. Malheureusement, parfois la manière la plus pragmatique de le faire est via un pragma; d'où le nom.
Eric Lippert
Ce n'est pas désactiver, c'est se cacher. Le problème sera toujours là juste que vous ne le verrez pas tel
quel

Réponses:

11

Je n'ai eu qu'une seule situation où j'ai désactivé un avertissement. Je considère les erreurs d'avertissement, donc je ne publierais pas normalement avec des avertissements. Cependant, lors du développement d'une API chez un client, j'ai rencontré le problème qu'une méthode qui était nécessaire dans une phase de migration par une application et qu'aucune autre ne devrait jamais utiliser devait être incluse dans la bibliothèque.

La meilleure façon de dire à tous les utilisateurs de l'API qu'ils ne devraient pas appeler cette méthode était de la marquer comme obsolète. Cependant, cela signifiait que le seul cas d'utilisation valide était marqué comme un avertissement de compilation.

Eric Lippert a écrit quelques articles sur les avertissements où vous trouverez des informations sur la façon dont l'équipe du compilateur pense aux avertissements.

Champs internes de types internes

Les directives d'utilisation inutilisées ne sont pas marquées d'avertissements

Rune FS
la source
10

Voici quelques avertissements où la documentation donne les raisons pour lesquelles vous voudrez peut-être les désactiver:

D'autres exemples incluent des avertissements sur l'utilisation de méthodes dépréciées si vous savez que vous souhaitez toujours utiliser l'ancienne méthode ou avoir des membres privés qui ne sont jamais lus localement, mais avec réflexion à la place.

D'après mon expérience, C # a moins besoin de désactiver les avertissements que d'autres langages tels que C ++. C'est en grande partie parce que, comme le dit Eric Lippert dans son blog , ils "essaient de réserver des avertissements uniquement aux situations où nous pouvons dire avec presque certitude que le code est cassé, trompeur ou inutile."

ICR
la source
3
Agréable. Je pense que le premier est le plus clair, car il fournit un cas très spécifique et une justification (le troisième, par exemple, montre un morceau de code qui ne passerait jamais en revue mon équipe). Cette question parle d'avertissements obsolètes / obsolètes. Fondamentalement, ils sont toujours nécessaires dans le code hérité, mais vous voulez décourager tout nouveau code de les utiliser. Le code hérité doit avoir les avertissements supprimés.
Greg Jackson
J'ai fait beaucoup de programmation macro dans Excel et j'ai dû désactiver les avertissements pour diverses raisons telles que la sauvegarde automatique, la sortie automatique, les notifications, etc. Bien sûr, vous ne pouvez pas être sur ces avertissements ...
Dave Mess
@ICR Je ne me souviens pas du tout d'avoir désactivé les avertissements du compilateur en Java. Tout ce que je fais, c'est éviter d'utiliser des méthodes obsolètes.
Mahmoud Hossam
@Mahmoud Je me retrouve très souvent obligé de supprimer les avertissements "non contrôlés" lorsque je fais quoi que ce soit de complexe, même à distance, avec des génériques. Mais il est probablement injuste de regrouper Java avec C ++ sur le front des avertissements ridicules - a modifié ma réponse.
ICR
@ICR Java impose l'utilisation de génériques pour assurer la sécurité des types dans les collections, alors que certains y voient une contrainte, je pense que c'est une fonctionnalité, cela rend l'écriture de code un peu pénible, mais cela sauve des vies, et oui, la sortie du compilateur C ++ est quelque peu effrayant en ce qui concerne STL ou quoi que ce soit avec des modèles.
Mahmoud Hossam
8

Un exemple en C dont je rencontre régulièrement des variantes:

int doSomething(int argument1)
{
#ifdef HARDWARE_TYPE_A
    performAction(argument1);
#else
    displayNotSupportedMessage();
#endif
}

L'argument n'est pertinent que sur certaines plates-formes, mais sur celles où il n'est pas pertinent, mon compilateur se plaindra, et puisque j'ai des avertissements convertis en erreurs, cela l'empêchera de se construire.

La conversion des avertissements en erreurs nécessite à peu près une trappe d'échappement pour "pas celui-ci, je sais mieux que le compilateur dans ce cas".

pjc50
la source
6

De nombreuses bibliothèques Java indispensables n'ont jamais été mises à jour pour éliminer le besoin de transtypages non sécurisés. La suppression de ces avertissements est nécessaire pour que d'autres avertissements plus importants soient remarqués et corrigés.

Kevin Cline
la source
5

Je fais du travail intégré et je me souviens d'un moment ou deux où j'ai désactivé les avertissements parce que je faisais quelque chose qui semblait inutile pour le compilateur, mais qui avait en fait des effets réels dans le matériel.

La seule autre fois, c'est quand je travaille sur des bases de code avec des idées disparates de certaines structures de données (comme comment représenter des tableaux d'octets - char ou char non signé?). Dans ces cas, je pourrais désactiver les avertissements car l'alternative consiste à passer des jours à parcourir le code et à modifier une partie ou à insérer des centaines de transtypages.

Michael Kohne
la source
3

Il existe plusieurs raisons de désactiver sélectivement les avertissements du compilateur, même pour les projets qui s'efforcent de respecter les meilleures pratiques.

  • Différents compilateurs (ou différentes versions des mêmes compilateurs) : les
    compilateurs gèrent les avertissements de manière subtile et différente. Donner des avertissements faussement positifs qui n'affectent pas les autres compilateurs. Dans ce cas, il peut être judicieux de désactiver l'avertissement pour ces compilateurs, au lieu de modifier un code valide pour atténuer un avertissement faussement positif qui n'affecte que certains compilateurs, en particulier pour les anciens compilateurs qui ne seront finalement pas pris en charge de toute façon.
  • Avec le code généré:
    certains avertissements liés à l'hygiène du code (code mort, corps en double d'instructions conditionnelles, comparaisons qui dépassent les limites de type) peuvent être ignorés en toute sécurité car ils sont inoffensifs et le compilateur les optimisera.
    La génération de code qui ne déclenche pas ces avertissements inoffensifs est bien sûr également une option, mais peut être plus difficile que sa valeur.
  • Avertissements pour le code externe:
    vous utilisez peut-être une implémentation de somme de contrôle qsort ou md5 bien connue qui est incluse dans votre projet. Le code est utilisé par de nombreux projets et connu pour bien fonctionner, mais il peut y avoir des avertissements pointilleux que vous corrigez normalement pour votre propre code.
    Cependant, pour le code externe, il peut être moins compliqué de désactiver simplement l'avertissement (en supposant qu'il est définitivement inoffensif).
  • Avertissements causés par les en-têtes du système:
    même si GCC / Clang prend en charge par exemple -isystem, il existe des cas où les différences d'en-têtes du système provoquent des avertissements qui peuvent être ignorés (peut-être qu'une fonction a une valeur de retour signée sur un système mais pas sur un autre), déclenchant des -Wsign-compareavertissements.
    Un autre cas peut être des macros définies dans les en-têtes du système, vous pouvez copier-coller les macros dans votre propre code pour les modifier, mais tout est préférable de ne pas avoir à vous soucier de la maintenance des macros à partir de bibliothèques tierces ... donc c'est mieux pour calmer l'avertissement (peut-être que la macro manque un casting provoquant -Wsign-conversionpar exemple).
  • Avertissements inutilisés dans le code de raccord:
    vous pouvez avertir des paramètres inutilisés, cependant lorsque vous supprimez une bibliothèque entière dans un seul fichier qui ne contient que des fonctions de raccord - il n'est pas utile de forcer (void)arg1; (void)arg2; (void)arg3; ...dans le corps de chaque fonction de raccord.
    Mieux vaut simplement supprimer -Wunused-parameterdans ce cas.

Notez que dans tous ces exemples, sa désactivation supposais les avertissements ne va pas se cacher des bugs réels, par exemple: -Wredundant-decls, -Wunused-parameter, -Wdouble-promotion, peut - être -Wpedantic... et que vous savez ce que vous faites!

ideasman42
la source
2

Valide ou non, il est parfois fait pour contourner la directive "traiter les avertissements comme des erreurs" sur le serveur de génération.

A part ça, je n'en pense pas non plus. Les avertissements des personnes handicapées sont généralement le signe d'un "laid hax" ...

David Božjak
la source
2

La dernière fois que nous avons désactivé certains avertissements, c'était parce qu'un stagiaire nous avait laissé un mauvais code. Je le fais beaucoup mieux, avec des limites de conversion claires remplaçant la représentation aléatoire des données.

En attendant, nous devions le compiler, et nous voulions que l'option "les avertissements soient des erreurs" soit activée, nous avons donc supprimé certains des avertissements.

David Thornley
la source
2

Actuellement, le seul avertissement que j'ignore est

  warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)  

Parce que Microsoft n'implémente pas la spécification C ++ (la documentation dit même qu'ils ne le font pas!) Et autorise les fonctions à déclarer des lancers spécifiques et toutes les fonctions ne peuvent lancer que throw () ou throw (...), c'est-à-dire rien ou tout.

Depuis HelpViewer 1.1:

 A function is declared using exception specification, which Visual C++ accepts but does not implement. Code with exception specifications that are ignored during compilation may need to be recompiled and linked to be reused in future versions supporting exception specifications. 
Casey
la source