Was aus i = i++ + 1; legal in C++17?

Bevor Sie beginnen zu Schreien Undefiniertes Verhalten, das ist explizit aufgelistet in N4659 (C++17)

  i = i++ + 1;        //the value of i is incremented

Doch in N3337 (C++11)

  i = i++ + 1;        //the behavior is undefined

Was geändert?

Von dem, was ich sammeln können, von [N4659 basic.exec]

Außer, wo bemerkt, Auswertungen von Operanden der einzelnen Operatoren und Teilausdrücke der einzelnen Ausdrücke sind nicht sequenzielle. [...] Die Wert-Berechnungen der Operanden eines operators sind sequenziert, bevor der Wert der Berechnung des Ergebnis des operators. Wenn eine Nebenwirkung auf ein Speicher ist nicht sequenzielle relativ zu entweder eine weitere Nebenwirkung, die auf die gleiche Speicherstelle oder ein Wert-Berechnung über den Wert jedes Objekts in die gleiche Erinnerung Lage, und Sie sind nicht potenziell gleichzeitigen, ist das Verhalten undefiniert.

Wo Wert definiert bei [N4659 basic.Typ]

Für trivial kopierbaren Arten, die Wert-Darstellung ist ein Satz von bits im Objekt-Repräsentation bestimmt, dass ein Wertdie einem einzelnen element eine von der Implementierung definierte Gruppe von Werten

Vom [N3337 basic.exec]

Außer, wo bemerkt, Auswertungen von Operanden der einzelnen Operatoren und Teilausdrücke der einzelnen Ausdrücke sind nicht sequenzielle. [...] Die Wert-Berechnungen der Operanden eines operators sind sequenziert, bevor der Wert der Berechnung des Ergebnis des operators. Wenn eine Nebenwirkung auf ein Skalar-Objekt ist nicht sequenzielle relativ zu entweder eine andere Nebenwirkung, auf die gleiche Skalare Objekt oder einen Wert-Berechnung mit dem Wert des gleichen Skalare Objekt, das Verhalten ist undefiniert.

Ebenso Wert definiert bei [N3337 basic.Typ]

Für trivial kopierbaren Arten, die Wert-Darstellung ist ein Satz von bits im Objekt-Repräsentation bestimmt, dass ein Wertdie einem einzelnen element eine von der Implementierung definierte Gruppe von Werten.

Sind Sie identisch, außer die Erwähnung der Gleichzeitigkeit, die nicht der Materie, und mit der Verwendung von Speicher statt scalar Objektwo

Arithmetische Typen, Aufzählungstypen, Zeiger-Typen, Zeiger auf member-Typen, die std::nullptr_t - und cv-qualifizierte Versionen dieser Typen werden zusammenfassend als Skalare Typen.

Die nicht auf das Beispiel.

Vom [N4659 expr.ass]

Dem Zuweisungsoperator (=) und dem zusammengesetzten Zuweisungsoperatoren alle in der Gruppe von rechts nach Links. Alle benötigen eine modifiable lvalue als Ihre linken Operanden und gibt nur ein lvalue bezogen auf die linke operand. Das Ergebnis ist in allen Fällen ein bit-Feld, wenn der linke operand ein bit-Feld. In allen Fällen der Abtretung ist sequenziert, die nach dem Wert-Berechnung des rechten und des linken Operanden, und bevor der Wert die Berechnung der Zuweisung Ausdruck. Der Rechte operand ist sequenziert, bevor der linke operand.

Vom [N3337 expr.ass]

Dem Zuweisungsoperator (=) und dem zusammengesetzten Zuweisungsoperatoren alle in der Gruppe von rechts nach Links. Alle benötigen eine modifiable lvalue als Ihre linken Operanden und gibt nur ein lvalue bezogen auf die linke operand. Das Ergebnis ist in allen Fällen ein bit-Feld, wenn der linke operand ein bit-Feld. In allen Fällen der Abtretung ist sequenziert, die nach dem Wert-Berechnung des rechten und des linken Operanden, und bevor der Wert die Berechnung der Zuweisung Ausdruck.

Nur mit dem Unterschied, dass der Letzte Satz fehlen in N3337.

Den letzten Satz allerdings, sollte keine Bedeutung, da der linke operand i ist weder "ein weiterer Nebeneffekt" noch "mit dem Wert des gleichen skalaren Objekt" als id-expression ist ein lvalue.

InformationsquelleAutor der Frage Passer By | 2017-12-07

Schreibe einen Kommentar