Si nous avons trois fonctions (foo, bar et baz) qui sont composées comme ça ...
foo(bar(), baz())
Y a-t-il une garantie par la norme C ++ que la barre sera évaluée avant baz?
Non, il n'y a pas une telle garantie. Il n'est pas spécifié selon la norme C ++.
Bjarne Stroustrup le dit aussi explicitement dans la section 6.2.2 de la 3e édition de "The C ++ Programming Language", avec quelques raisonnements:
Un meilleur code peut être généré en l'absence de restrictions sur l'ordre d'évaluation des expressions
Bien que techniquement, cela se réfère à une partie antérieure de la même section qui dit que l'ordre d'évaluation des parties d'une expression est également non spécifié, c'est-à-dire
int x = f(2) + g(3); // unspecified whether f() or g() is called first
Il n'y a pas d'ordre spécifié pour bar () et baz () - la seule chose que le Standard dit est qu'ils seront tous les deux évalués avant que foo () ne soit appelé. À partir de la norme C ++, section 5.2.2 / 8:
la source
bar
, puis la ligne 1 debaz
, puis la ligne 2 debar
, etc.), ce qui est également agréable. :-)Depuis [5.2.2] Appel de fonction,
Par conséquent, il n'y a aucune garantie qui
bar()
fonctionnera avantbaz()
, seulement celabar()
etbaz()
sera appelé avantfoo
.Notez également dans [5] Expressions que:
même si vous demandiez si
bar()
courra avantbaz()
dansfoo(bar() + baz())
, l'ordre est encore non précisée.la source
&
,&&
garantit une évaluation de gauche à droite: le deuxième opérande n'est pas évalué si le premier opérande l'estfalse
."C ++ 17 spécifie l'ordre d'évaluation des opérateurs qui n'était pas spécifié jusqu'à C ++ 17. Voir la question Quelles sont les garanties d'ordre d'évaluation introduites par C ++ 17? Mais note ton expression
a toujours un ordre d'évaluation non spécifié.
la source
En C ++ 11, le texte correspondant se trouve dans 8.3.6 Arguments par défaut / 9 (c'est moi qui souligne )
Le même verbiage est également utilisé par la norme C ++ 14 et se trouve dans la même section .
la source
Comme d'autres l'ont déjà souligné, la norme ne donne aucune indication sur l'ordre d'évaluation pour ce scénario particulier. Cet ordre d'évaluation est ensuite laissé au compilateur, et le compilateur peut avoir une garantie.
Il est important de se rappeler que le standard C ++ est en réalité un langage pour instruire un compilateur sur la construction de code assembleur / machine. La norme n'est qu'une partie de l'équation. Lorsque la norme est ambiguë ou est spécifiquement définie par une implémentation, vous devez vous tourner vers le compilateur et comprendre comment il traduit les instructions C ++ en véritable langage machine.
Donc, si l'ordre d'évaluation est une exigence, ou du moins importante, et que la compatibilité entre compilateurs croisés n'est pas une exigence, examinez comment votre compilateur finira par assembler cela, votre réponse pourrait finalement se trouver là. Notez que le compilateur pourrait changer sa méthodologie à l'avenir
la source