Was sind die evaluation, um Garantien eingeführt, die von der C++17?
Was sind die Auswirkungen der Europawahlen C++17 evaluation Bestellung garantiert (P0145) auf typische C++ - code?
Was ändert es, über Dinge wie
i=1;
f(i++, i)
und
std::cout << f() << f() << f() ;
oder
f(g(),h(),j());
- Bezogen auf Reihenfolge der Auswertung von Einsatz-Anweisung in C++ und dieser code aus "Die C++ Programmiersprache", 4. Auflage § 36.3.6 haben gut definierte Verhalten?, die beiden sind abgedeckt durch das Papier. Die erste könnte man eine schöne zusätzliche Beispiele in Ihrer Antwort unten.
- Auch etwas im Zusammenhang: c++ - 17-Evaluierung, um mit operator-überladen von Funktionen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einige häufige Fälle, in denen die Auswertung, um bisher unbekannter, angegeben werden und gültig mit
C++17
. Einige Undefiniertes Verhalten ist jetzt statt, nicht angegeben.war undefiniert, aber ist jetzt nicht angegeben. Speziell, was nicht angegeben ist, ist die Reihenfolge, in der jedes argument
f
bewertet wird im Verhältnis zu den anderen.i++
könnten ausgewertet werden, bevori
oder vice-versa. In der Tat, es könnte bewerten, der zweite Aufruf in einer anderen Reihenfolge, obwohl Sie unter dem gleichen compiler.Jedoch die Bewertung der einzelnen Argumente ist erforderlich vollständig ausführen, mit allen Nebenwirkungen, vor der Ausführung von einem anderen argument. So könnte man
f(1, 1)
(zweites argument zuerst ausgewertet) oderf(1, 2)
(erstes argument zuerst ausgewertet). Aber Sie werden nie wiederf(2, 2)
oder irgendetwas anderes in der Natur.Wurde nicht spezifiziert, aber werden kompatibel mit operator-Vorrang, so dass die erste Bewertung von
f
kommt zuerst in den Bach. (Beispiele unten).noch unbekannter Bewertung Reihenfolge g, h, j. Beachten Sie, dass für
getf()(g(),h(),j())
die Regeln besagen, dassgetf()
werden ausgewertet, bevorg,h,j
.Beachten Sie auch das folgende Beispiel aus dem Vorschlag text:
Beispiel kommt aus Die C++ - Programmiersprache, 4. Auflage, Stroustrup, und verwendet werden, um unspezifische Verhalten, aber mit C++17 es wird wie erwartet funktionieren. Es gab ähnliche Probleme mit fortsetzbare Funktionen (
.then( . . . )
).Als weiteres Beispiel betrachten wir die folgenden:
Mit C++14 und bevor wir können (und werden) die Ergebnisse erhalten wie
statt
Beachten Sie, dass die oben ist in der Tat das gleiche wie
Aber noch, bevor C++17 gab es keine Garantie, dass die ersten Aufrufe kommen würde, zuerst in den stream.
Referenzen: Von der akzeptiert Vorschlag:
Bearbeiten Hinweis: Meine ursprüngliche Antwort falsch interpretiert
a(b1, b2, b3)
. Die Reihenfolge derb1
,b2
,b3
ist noch nicht spezifiziert. (danke @KABoissonneault, alle Kommentatoren.)Allerdings, (wie @Yakk Punkte), und das ist wichtig: Auch wenn
b1
,b2
,b3
sind nicht-triviale Ausdrücke, jeder von Ihnen sind vollständig ausgewertet und gebunden an die jeweilige Funktion parameter, bevor die andere gestartet werden ausgewertet. Der standard besagt dies wie folgt:Jedoch einer dieser neuen Sätze fehlen github Entwurf:
Beispiel ist es. Es löst eine Jahrzehnte-alte Probleme (Wie bereits erklärt, von Herb Sutter) mit Ausnahme der Sicherheit, wo Dinge wie
würde Auslaufen, wenn der ruft
get_raw_a()
werfen würde, bevor die anderenraw-pointer gebunden war, um es in den smart-pointer-parameter.
edit: wie bereits von T. C. das Beispiel ist fehlerhaft, da unique_ptr Bau von raw-pointer explizit ist, zu verhindern das kompilieren.
Beachten Sie auch diese klassische Frage (tagged C, nicht C++):
ist noch nicht definiert.
std::cout
wird tatsächlich eine vorgeschriebene Reihenfolge; die anderen undefiniert bleiben wie vorher. Ich meine, ich könnte falsch sein, aber das ist, was ich verstanden von dem Vorschlag, dass tatsächlich C++17.a
, dannb
, dannc
, dannd
" und dann zeigta(b1, b2, b3)
, was darauf hindeutet, dass alleb
Ausdrücke sind nicht notwendigerweise ausgewertet, in beliebiger Reihenfolge (ansonsten wäre esa(b, c, d)
)a(b1()(), b2()())
können, umb1()()
undb2()()
in beliebiger Reihenfolge, aber es nicht tunb1()
dannb2()()
dannb1()()
: es kann nicht mehr interleave Ihren Ausführungen. Kurz gesagt, "8. ALTERNATE BEWERTUNG REIHENFOLGE FÜR die FUNKTION RUFT" war Teil des genehmigten ändern.f(i++, i)
wurde nicht definiert. Es ist nun nicht spezifiziert. Stroustrup 's string Beispiel war wahrscheinlich unspezifisch, nicht undefiniert. ` f(get_raw_a(),get_raw_a ());" nicht kompilieren, da die entsprechendenunique_ptr
Konstruktor ist explicit. Schließlichx++ + ++x
ist nicht definiert, Punkt.*foo() += x;
ist das Lesen vonx
sequenziert, bevor der Anruf zufoo
oder lediglich vor dem Lesen der Adresse, diefoo
zurückgegeben? Das ausführen das Lesen vonx
bevor der Anruf wäre oft nötig machen, schob ein extra Wort auf dem stack verglichen mit Lesen nach.a{b1, b2, b3}
Folgen die Funktionsaufrufe, d.h. "die Bewertung der einzelnen Argumente ist erforderlich, um vollständig ausführen"?ìnt x, *y; y = &x; cout << *y << x++;
zurück?Interleaving ist es verboten, in C++17
In C++14, die folgende war nicht ungefährlich:
Gibt es vier Operationen, die hier vorkommen, während der Aufruf der Funktion
new A
unique_ptr<A>
Konstruktornew B
unique_ptr<B>
KonstruktorDie Bestellung dieser war völlig unbekannter, und so ein perfekt gültigen Bestellung ist (1), (3), (2), (4). Wenn Sie diese Reihenfolge gewählt wurde und (3) wirft, dann ist der Speicher aus (1) Leckagen - wir noch nicht ausgeführt haben (2) aber, die haben verhindert das Auslaufen.
In C++17, die neuen Regeln verbieten interleaving. Von [intro.Ausführung]:
Dort ist in einer Fußnote zu diesem Satz liest:
Dies lässt uns mit zwei gültigen Ordnungen: (1), (2), (3), (4) oder (3), (4), (1), (2). Es ist nicht angegeben, die Bestellung ist aufgenommen, aber diese beiden sind sicher. Alle Ordnungen, in denen (1) (3) sowohl passieren, bevor (2) und (4) sind nun verboten.
Ich habe festgestellt, dass einige Notizen über die Auswertung eines Ausdrucks um:
Funktion Argumente?
In P0145R3.Die Verfeinerung der Auswertung eines Ausdrucks, Um für die Idiomatischen C++ die ich gefunden habe:
Aber ich fand es nicht in der standard -, statt in der Norm die ich gefunden habe:
So, ich gegenüber entsprechend Verhalten in drei Compiler für 14-und 17-standards. Die erkundeten code:
Ergebnisse (die mehr konsistent ist clang):
HTML: