Ordre d'évaluation des paramètres de la fonction c++

si nous avons trois fonctions (foo, bar, et baz) qui sont composées comme ceci...

foo(bar(), baz())

la norme C++ garantit-elle que bar sera évalué avant baz?

73
demandé sur Clark Gaebel 2010-05-29 15:55:41

6 réponses

Non, il n'y a pas de garantie. Il n'est pas défini selon le standard c++.

Bjarne Stroustrup le dit aussi explicitement dans" The C++ Programming Language "3rd edition section 6.2.2, avec quelques explications:

Meilleur code peut être généré dans le absence de restrictions à l'expression ordre d'évaluation

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 sont également non définis, i.e.

int x = f(2) + g(3);   // undefined whether f() or g() is called first
86
répondu Eli Bendersky 2018-04-28 19:09:32

il n'y a pas d'ordre spécifié pour bar() et baz() - La seule chose que la norme dit est qu'ils seront tous les deux évalués avant que foo() soit appelé. De la norme C++, section 5.2.2 / 8:

L'ordre d'évaluation des arguments est indéterminé.

20
répondu 2010-05-29 12:07:41

De [5.2.2] appel de la Fonction,

L'ordre d'évaluation des arguments n'est pas spécifié. Tous les effets secondaires des évaluations de l'expression de l'argument prennent effet avant que la fonction est entrée.

par conséquent, il n'ya aucune garantie que bar() avant baz() , seulement que bar() et baz() sera appelé avant foo .

également note du [5] Expressions qui:

sauf indication contraire [par exemple, règles spéciales pour && et || ], l'ordre d'évaluation des opérandes des opérateurs individuels et des sous-expressions des expressions individuelles, et l'ordre dans lequel les effets secondaires ont lieu, n'est pas précisé.

donc même si vous demandiez si bar() sera exécuté avant baz() dans foo(bar() + baz()) , l'ordre est toujours non spécifié.

14
répondu Daniel Trebbien 2010-05-29 12:31:47

C++17 spécifie l'ordre d'évaluation pour les 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 notez votre expression

foo(bar(), baz())

a encore un ordre d'évaluation non spécifié.

8
répondu S.M. 2017-12-03 05:24:28

En C++11, le texte peut être trouvé dans 8.3.6 des arguments par Défaut/9 (l'Emphase est mienne)

les arguments par défaut sont évalués chaque fois que la fonction est appelée. l'ordre d'évaluation des arguments de fonction est non spécifié . Par conséquent, les paramètres d'une fonction ne doivent pas être utilisés dans un argument par défaut, même s'ils ne sont pas évalués.

le même verbiage est utilisé par C++14 standard aussi bien, et se trouve sous la même section .

2
répondu R Sahu 2017-12-02 07:15:38

Comme d'autres l'ont déjà souligné, la norme ne donne aucune indication sur l'ordre de l'évaluation pour ce scénario particulier. Cet ordre d'évaluation est alors laissé au compilateur, qui peut avoir une garantie.

il est important de se rappeler que la norme C++ est en fait un langage pour instruire un compilateur sur la construction d'un code assembleur/machine. La norme n'est qu'une partie de l'équation. Lorsque la norme est ambiguë ou est spécifiquement implémentation définie vous devez vous tourner vers le compilateur et comprendre comment il traduit les instructions C++ en vrai langage machine.

donc, si l'ordre d'évaluation est une exigence, ou au moins important, et être compatible avec les compilateurs croisés n'est pas une exigence, étudiez comment votre compilateur finira par rassembler tout cela, votre réponse pourrait se trouver là. Notez que le compilateur pourrait changer sa méthodologie dans le futur

0
répondu Erudite Programmer 2017-12-09 18:56:55