Dans l'expression x * y
, les termes x
et y
sont non séquencés. C'est l'une des trois possibilités de séquençage de relations, qui sont:
-
A
séquencé-avant B
: A
doit être évalué, avec tous les effets secondaires complet, avant d' B
commence evaluationg
-
A
et B
pour une période indéterminée-séquencé: l'un des deux cas suivants est vrai: A
est séquencé en-avant B
ou B
est séquencé en-avant A
. Il est non spécifié lequel de ces deux cas, titulaire d'.
-
A
et B
non: Il n'y a pas de séquençage relation définie entre A
et B
.
Il est important de noter que ce sont les paires de relations. On ne peut pas dire "x
est non". Nous pouvons seulement dire que les deux opérations sont séquencé à l'égard les uns des autres.
Il est également important que ces relations sont transitifs; et les deux dernières relations sont symétriques.
non spécifié est un terme technique qui signifie que la Norme spécifie un nombre de résultats possibles. C'est différent de comportement indéfini qui signifie que la Norme ne couvre pas les comportements à tous. Voir ici pour plus de lecture.
Le déplacement sur le code x * f(x)
. C'est identique à l' f(x) * x
, parce que, comme discuté ci-dessus, x
et f(x)
sont des non, avec le respect les uns des autres, dans les deux cas.
Nous en arrivons maintenant au point où plusieurs personnes semblent venir décoller. L'évaluation de l'expression f(x)
est séquencé à l'égard x
. Cependant, il n'est pas suivi toute les instructions à l'intérieur du corps de la fonction d' f
sont également séquencé à l'égard x
. En fait, il y a le séquençage des relations liées à tout appel de fonction, et ces relations ne peuvent pas être ignorés.
Voici le texte de C++14:
Lors de l'appel d'une fonction (que ce soit ou non la fonction inline), chaque valeur de calcul et des effets secondaires associés avec n'importe quel argument de l'expression, ou avec le suffixe expression désignant la fonction appelée, est séquencée avant l'exécution de chaque instruction ou de l'expression dans le corps de la fonction appelée. [Note: la Valeur des calculs et des effets secondaires associés avec différentes expressions d'arguments sont séquencé. -la note de fin ]
Chaque évaluation dans la fonction appelante (y compris d'autres appels de fonction) qui n'est pas spécifiquement séquencée avant ou après l'exécution du corps de la fonction appelée est pour une période indéterminée séquencéavec
l'égard de l'exécution de la fonction appelée.
avec la note de bas de page:
En d'autres termes, la fonction d'exécutions ne pas entrelacer les uns avec les autres.
Le texte en gras indique clairement que les deux expressions:
-
Un:
x = x + 1;
à l'intérieur d' f(x)
-
B: l'évaluation la première
x
dans l'expression x * f(x)
leur relation est la suivante: pour une période indéterminée séquencé.
Le texte concernant un comportement indéterminé et le séquençage de l':
Si un effet indésirable sur un scalaire objet est séquencé par rapport à un autre effet secondaire sur le même scalaire objet ou d'une valeur de calcul à l'aide de la valeur de la même scalaire objet, et ils ne sont pas potentiellement concurrentes (1.10), le comportement est indéfini.
Dans ce cas, la relation est pour une période indéterminée séquencé, pas séquencé. Donc, il n'y a pas de comportement indéfini.
Le résultat est plutôt quelconque selon qu' x
est séquencée avant de x = x + 1
ou de l'autre manière autour. Donc, il y a que deux résultats possibles, 42
et 49
.
Dans le cas où quelqu'un avait des scrupules au sujet de l' x
en f(x)
, le texte suivant s'applique:
Lors de l'appel d'une fonction (que ce soit ou non la fonction inline), chaque valeur de calcul et des effets secondaires associés avec n'importe quel argument de l'expression, ou avec le suffixe expression désignant la fonction appelée, est séquencée avant l'exécution de chaque instruction ou de l'expression dans le corps de la fonction appelée.
Donc, l'évaluation de l' x
est séquencée avant de x = x + 1
. Ceci est un exemple d'un evlauation qui tombe sous le cas de "spécialement séquencée avant" dans la citation en gras ci-dessus.
Note de bas de page: le comportement est exactement le même en C++03, mais la terminologie est différente. En C++03, nous disons qu'il y a un point de séquence à l'entrée et à la sortie de chaque appel de fonction, donc l'écriture d' x
à l'intérieur de la fonction est séparée de la lecture de x
en dehors de la fonction d'au moins un point de séquence.