10
votes

Quel est le point d'émettre un avertissement de compilateur pour "tandis que (vrai)" et ne pas en émetteur pour "pour (;;)"?

Lorsque je compile le code C ++ avec Visual C ++ 9 avec "Niveau d'avertissement 4", ce qui suit: xxx

et les suivants: xxx

Les deux déclencheurs C4127: L'expression conditionnelle est constante AVERTISSEMENT, mais les suivantes: xxx

compile sans avertissement.

Pourquoi cette différence , en particulier entre la deuxième et la troisième variante?


3 commentaires

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 , surtout lors de l'utilisation de boost.


Connexes:

5 Réponses :


4
votes

Le pour (;;) construct est le moyen canonique de intentionnellement code une boucle "sans fin". Je pouvais imaginer que les concepteurs du compilateur ne souhaitaient pas générer un avertissement pour cela.


3 commentaires

Je dirais que la causalité est l'autre solution - c'est Canonical parce que 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.



10
votes

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.


0 commentaires

4
votes

aucun point. Après tout, la spécification de languette indique (6,5,3 / 2 $),

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).

donc pour (;;) est équivalent à tandis que (vrai) 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!

-

Si le compilateur décide de donner un avertissement, alors à mon avis, le compilateur doit donner un avertissement lorsque la condition est manquante par opposition au moment présent, de sorte que l'avertissement serait interprété comme Astuce pour programmeur pour mentionner son clairement et explicitement .

je veux dire, pour (;;) est plus susceptible d'être une typographie que la mention explicite de condition dans pour (; vrai;) . Ce dernier raconte l'intention claire et explicite du programmeur. Comme Steve dit en commentaire:

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.

L'intention explicite ne devrait pas recevoir d'avertissement, tandis que l'intention implicite devrait recevoir!


6 commentaires

Pas mon bowvote, mais je pense que l'équivalence est un hareng rouge. Pour un autre exemple, selon la norme si (x = y) est équivalent à si (((x = y)) , mais GCC met en garde pour le premier et non le dernier . Pour une valeur INT Y, char x = y est équivalent à char x = (char) y , 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) 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) , 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 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 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.




7
votes

La raison est simple, bien que stupide.

Il est important de diagnostiquer la boucle infinie, mais cela pourrait ne pas être évident: xxx

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.

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 ou false Conditions qu'il peut trouver, même quand ils sont déjà clairement indiqué dans le code.


0 commentaires