Dans les macros C, doit-on préférer faire {...} while (0,0) sur do {...} while (0)?
-
13-09-2019 - |
Question
Un client a récemment effectué une analyse statique de C codebase de mon employeur et nous a donné les résultats. Parmi les correctifs utiles a la demande de changer le fameux
La solution Eh bien, je vais une réponse: Y at-il une raison légitime pour laquelle on devrait préférer la deuxième forme de la macro ...? Non. Il n'y a aucune raison légitime. Les deux exploitez toujours à faux, et tout compilateur décent probablement tourner le second dans le premier dans l'assemblée de toute façon. S'il n'y avait aucune raison pour qu'il soit invalide dans certains cas, C est depuis bien assez longtemps pour cette raison d'être découvert par les gourous plus que moi. Si vous aimez votre code faisant les yeux-y hibou à vous, utilisez
while(0,0)
. Dans le cas contraire, utilisez ce que le reste du monde de la programmation C utilise et dire outil d'analyse statique de votre client pour le pousser.
Autres conseils
Juste une supposition pour expliquer pourquoi ils peuvent suggérer d'utiliser
do { ... } while(0,0)
sur
do { ... } while(0)
Bien qu'il n'y ait pas de différence de comportement et ne devrait y avoir aucune différence de coût d'exécution entre les deux.
Je pense que l'outil d'analyse statique se plaint de la boucle de while
étant contrôlée par une constante dans le cas le plus simple et ne pas lorsque 0,0
est utilisé. La suggestion du client est probablement juste pour qu'ils ne reçoivent pas un tas de faux positifs de l'outil.
Par exemple, je parfois rencontré des situations où je veux avoir une instruction conditionnelle contrôlée par une constante, mais le compilateur se plaindra d'un avertissement au sujet d'une expression conditionnelle à une constante évaluation. Ensuite, je dois sauter à travers quelques cerceaux pour obtenir le compilateur pour arrêter de se plaindre (puisque je n'aime pas avoir faux messages d'avertissement).
est l'une de la suggestion de votre client les cerceaux que j'ai utilisé pour calmer cet avertissement, mais dans mon cas, il ne contrôlait pas une boucle de while
, il devait faire face à une affirmation « toujours échoue ». De temps en temps, je vais avoir une zone de code qui ne devrait jamais exécuter (peut-être le cas par défaut d'un commutateur). Dans cette situation, je pourrais avoir une affirmation qui échoue toujours avec un certain message:
assert( !"We should have never gotten here, dammit...");
Mais, au moins un compilateur que j'utilise un message d'avertissement au sujet de l'expression évaluation toujours faux. Cependant, si je change à:
assert( ("We should have never gotten here, dammit...", 0));
L'avertissement disparaît, et tout le monde est heureux. Je suppose que l'outil d'analyse statique de même que votre client serait aussi. Notez que je cache généralement que peu de cerceau sauter derrière une macro comme:
#define ASSERT_FAIL( x) assert( ((x), 0))
Il est peut-être agréable d'être en mesure de dire au vendeur d'outils pour résoudre le problème, mais il pourrait y avoir des cas légitimes où ils ne veulent réellement diagnostiquer une boucle étant contrôlée par une expression booléenne constante. Sans parler du fait que, même si vous convaincre un fournisseur d'outils pour faire un tel changement, cela ne vous aide pas pour l'année suivante ou, afin qu'il puisse prendre pour obtenir réellement une solution.
Utilisation de while(0,0)
empêche compilateur Microsoft de génération d'un avertissement au sujet d'un état qui est une constante (avertissement C4127).
Lorsque cet avertissement est activé (par exemple avec / ou W4 / mur), il peut être arrêté au cas par cas avec ce petit truc sympa ( voir cet autre fil ).
EDIT: Depuis Visual Studio 2017 15,3, while(0)
n'émet pas d'avertissements plus (voir Constant Conditionals). Vous pouvez vous débarrasser de votre (0,0)
!