Lorsque je compile le code C ++ avec Visual C ++ 9 avec "Niveau d'avertissement 4", ce qui suit: et les suivants: p> Les deux déclencheurs compile sans avertissement. P> Pourquoi cette différence , en particulier entre la deuxième et la troisième variante? p> p> C4127: L'expression conditionnelle est constante code> AVERTISSEMENT, mais les suivantes: p>
5 Réponses :
Le pour (;;) code> construct est le moyen canonique de intentionnellement em> code une boucle "sans fin". Je pouvais imaginer que les concepteurs du compilateur ne souhaitaient pas générer un avertissement pour cela. P>
Je dirais que la causalité est l'autre solution - c'est Canonical parce que i> Il n'émettant pas d'avertissement sur une certaine série de compilateurs populaires.
Je ne pense pas que c'est même canonique si vous incluez des compilateurs autres que vs. Je ne pense pas que GCC met en garde à ce sujet?
@JK: Vous avez réellement raison, GCC n'empêche pas l'une de ces constructions. Je n'ai pas testé pour cela, vient de spéculer.
La raison de l'avertissement L'utilisateur d'expressions conditionnelles constantes est d'aider à éviter les bogues où l'expression finit par être constante (par exemple, en raison d'une faute de frappe). Dans le dernier cas, il n'y a pas d'expression, il n'ya donc aucun risque d'être accidentellement constant. P>
aucun point. Après tout, la spécification de languette indique (6,5,3 / 2 $), p>
soit ou à la fois de la condition et L'expression peut être omise.
a L'état manquant rend l'implicite tandis que la clause équivalente à tandis que (vrai). strong> p> blockQuote> donc
pour (;;) code> est équivalent à
tandis que (vrai) code> même selon la norme. Par conséquent, je ne vois aucune raison pour que le compilateur devrait donner un avertissement dans un cas, mais pas dans l'autre! P>
- p>
Si le compilateur décide de donner un avertissement, alors à mon avis, le compilateur doit donner un avertissement lorsque la condition est manquante em> par opposition au moment présent, de sorte que l'avertissement serait interprété comme Astuce em> pour programmeur pour mentionner son em> clairement et explicitement em>. p>
je veux dire,
pour (;;) code> est plus susceptible d'être une typographie forte> que la mention explicite em> de condition dans
pour (; vrai;) code>. Ce dernier raconte l'intention claire et explicite du programmeur. Comme
Steve Strong> dit en commentaire: P> pour une valeur INT y, char x = y est équivalent à char x = (char) y, mais Vous voudrez peut-être un avertissement pour un Conversion implicite de rétrécissement sur le d'abord mais pas la seconde. p> blockQuote>
L'intention explicite ne devrait pas recevoir d'avertissement, tandis que l'intention implicite devrait recevoir! strong> p>
Pas mon bowvote, mais je pense que l'équivalence est un hareng rouge. Pour un autre exemple, selon la norme si (x = y) code> est équivalent à
si (((x = y)) code>, mais GCC met en garde pour le premier et non le dernier . Pour une valeur INT Y,
char x = y code> est équivalent à
char x = (char) y code>, mais vous voudrez peut-être un avertissement pour une conversion implicite de rétrécissement sur le premier mais pas la seconde.
vrai, mais je trouve l'idée que, alors que (vrai) est susceptible d'être une faute de frappe à ne pas convaincre. imho vs est trop difficile ici
@JK: Je suis certainement d'accord que tandis que (vrai) code> n'est probablement pas une faute de frappe. En fait, je le préfère, alors Msvc m'énerve. Plutôt qu'une faute de frappe, il peut s'agir d'une expansion de préprocesseur
tandis que (condition) code>, où la condition est définie accidentellement sur quelque chose toujours vrai. Au moins, j'ai toujours supposé que c'est ce qui se passait dans l'esprit de MS quand ils ont inventé l'avertissement. IMO L'avertissement ne doit être émis que s'il n'y a pas non plus
break code> dans la boucle. Ou pas du tout - des boucles infinies accidentelles ont tendance à ne pas être les bugs subtlest une fois que vous avez exécuté le code ...
@Steve: J'ai cité votre commentaire dans mon message. J'espère que ça ne vous dérange pas. :-)
@Steve: Indecidable ... Si votre boucle est interrompue d'une exception, le compilateur ne peut pas savoir que s'il inspecte le corps des appels de fonction ... qui sont évidemment dans une autre unité de traduction.
@Mattheiu: OK, mais c'est juste plus de raison pas i> pour avertir si le code appelle du TU. Ce serait une analyse beaucoup plus difficile, cependant, que de faire ce que MS a fait. Ils ont décidé que les boucles qui ne peuvent pas terminer dans la condition de boucle sont dignes d'un avertissement, sauf qu'ils ont permis à une syntaxe particulière de supprimer l'avertissement. J'ai donc une plainte que la syntaxe qu'ils choisissaient n'est pas ma syntaxe privilégiée et une deuxième plainte distincte que je pense que l'avertissement est de toute façon excessive.
AVERTISSEMENT DE COMPILATEUR SONT ICI POUR ATTEINDRE ATTEINDRE PASSER DES BOGUES POTENTIELS. Utilisation d'un dans une telle situation, dans la construction optimisée, le compilateur sera probablement déduire que la condition est toujours vraie (puisqu'un entier non signé ne peut pas être inférieur à 0). Donc, il est nécessaire de détecter une condition toujours code> true code> dans Vous pouvez lire ici , comment la décision d'ajouter un avertissement ou non dans Visual Studio est prise (l'exemple concerne TRUE code> condition dans un
pendant que code> est probablement une erreur. Pour un exemple, dans le code suivant, c'est probablement un bug, et j'aimerais que le compilateur me prévalait de cela:
pendant code> boucle. Je pense que quiconque a écrit la détection d'une telle erreur n'a pas eu cas particulier le cas
tandis que (vrai) code>, car il existe un moyen simple de faire une boucle infinie avec
pour (;;) code>. P>
C # code> mais je suppose que l'équipe a la même règle de prévention
c ++ code>). p> p>
La raison est simple, bien que stupide.
Il est important de diagnostiquer la boucle infinie, mais cela pourrait ne pas être évident: p> C'est une excellente caractéristique de Un compilateur pour produire un avertissement pour un test tautologique, c'est-à-dire un test qui s'avère toujours vrai ou toujours faux, car il n'est pas évident quand il provient d'une expansion macro ou dans un contexte dépendant. P> Il semble juste que VC ++ a poussé un peu trop loin ici, et au lieu d'envisager des conditions tautologiques avertit pour tous les true code> ou
false code> Conditions qu'il peut trouver, même quand ils sont déjà clairement indiqué dans le code. P> p>
Parce qu'il n'y a pas d'expression conditionnelle dans la troisième déclaration ... Bien qu'il y ait en deuxième et troisième ... Comment le compilateur peut-il générer un avertissement en ce qui concerne l'expression conditionnelle sans y avoir?
Je finis généralement par désactiver C4127 avec
#pragma Avertissement Code>, surtout lors de l'utilisation de boost.
Connexes: