Lassen Sie uns Ihren Code umschreiben als
E1 = (E2 = E3)
wo E1 ist der Ausdruck a
, ist E2 der Ausdruck a += 1
und E3 ist der Ausdruck 10
. Hier haben wir festgestellt, dass der Zuweisungsoperator von rechts nach links gruppiert ist (§5.17/1 in C++ 11 Standard).
§5.17/1 Außerdem heißt es:
In allen Fällen ist die Zuordnung nach dem Wert Berechnung der rechten und linken Operanden sequenziert wird und bevor der Wert Berechnung der Zuweisungsausdruck.
Angewandt auf unseren Ausdruck bedeutet, dass wir zuerst die Unterausdrücke E1
und E2 = E3
bewerten müssen. Beachten Sie, dass zwischen diesen beiden Auswertungen keine "sequenziert-vorher" -Beziehung besteht, die jedoch keine Probleme verursacht.
Die Auswertung der ID-expressionE1
trivial ist (das Ergebnis ist a
selbst). Die Auswertung des ZuordnungsausdrucksE2 = E3
läuft wie folgt ab:
Zuerst müssen beide Teilausdrücke ausgewertet werden. Die Auswertung des LiteralsE3
ist wiederum trivial (ergibt einen Pr-Wert von 10).
Die Auswertung der (Verbindung) ZuweisungsausdruckE2
in den folgenden Schritten durchgeführt wird:
1) Das Verhalten von a += 1
entspricht a = a + 1
a
aber wird nur einmal ausgewertet (§5.17/7) . Nach dem Auswerten der Unterausdrücke a
und 1
(in einer beliebigen Reihenfolge) wird ein lvalue-to-rvalue Umwandlung auf a
konvertiert, um den in a
gespeicherten Wert zu lesen.
2) Die Werte von a
(die 0
) und 1
ist addiert (a + 1
) und das Ergebnis dieser Addition ist ein prvalue Wert 1
.
3) Bevor wir das Ergebnis der Zuweisung a = a + 1
berechnen können, wird der Wert des Objekts, auf das der linke Operand verweist, durch den Wert des rechten Operanden (§5.17/2) ersetzt. Das Ergebnis von E2
ist dann ein L-Wert, der sich auf den neuen Wert 1
bezieht.Beachten Sie, dass der Nebeneffekt (Aktualisieren des Werts des linken Operanden) vor der Wertberechnung des Zuweisungsausdrucks sequenziert wird. Dies ist § 5.17/1 oben zitiert.
Nachdem wir nun die Unterausdrücke E2
und E3
ausgewertet haben, ist der Wert des Ausdrucks E2
bezieht sich durch den Wert von E3
ersetzt wird, die 10
ist. Daher ist das Ergebnis von E2 = E3
ein Wert von 10
.
Schließlich bezieht sich der Ausdruck Wert E1
zu E2 = E3
durch den Wert des Ausdrucks ersetzt wird, die wir 10
berechnet werden. Daher enthält die Variable a
den Wert 10
.
Da alle diese Schritte gut definiert sind, liefert der gesamte Ausdruck einen genau definierten Wert.
Randnotiz: Das Überprüfen des Ergebnisses eines möglicherweise nicht definierten Ausdrucks sagt uns nicht, ob es tatsächlich UB ist oder nicht. Es kann UB sein und ein korrektes Ergebnis liefern. – jrok
@jrok das ist ein Beispiel-Code, vielleicht sogar ein SSCCE, wie SO erfordert, dass ich * gültigen Code *. Ich habe es aus Neugier getestet, aber ich merke, dass es nichts beweist; daher habe ich es nicht einmal erwähnt. – Dariusz
@jrok - es kann "korrekte" Ergebnisse erzeugen. Die Zitate sind wichtig. '' –