Zusammenspiel von RAII-Mutex und return / Standard-Advokat gesucht
-
Moin moin,
ich bräuchte mal Hilfe zum 2003er Standard.
Folgender Code:
class A { X x_; X foo() { scope_guard<Something> guard; return x_; } };Ist es garantiert, dass das Temporary für den return-Wert *vor* dem Destruktor des Scope-Guards ausgeführt wird?
Der 2003er Standard sagt in 6.6.3/3 nur "the expression is evaluated just before the function returns to its caller.", was ich sehr schwammig finde. Zumal hier auch noch copy constructor elision reinspielen kann.
Falls es garantiert ist, bitte einen entsprechenden Verweis auf den Standard.
Danke & Gruß
-
Der Ausdruck...
return x_;...wird in dem Wege ausgewertet, dass eine Kopie von x_ erstellt und in die Zielvariable der Rückgabe gespeichert wird, danach wird die Funktion nicht forgesetzt. Folglich werden bei Beendigung der Funktion Destruktoren aufgerufen und anschließend wird zum Funktionsaufrufer zurückgekehrt.
...the expression is evaluated just before the function returns to its caller.
Diese Beschreibung ist somit doch ziemlich genau.
-
Ich habe nur den C++11 Standard, aber
C++11 6.6.3/2 schrieb:
The value of the expression is implicitly converted to the return type of the function in which it appears.
müsste so auch im C++03er stehen.
Das bedeutet:
int main() { A a; const X& f = a.foo(); /* 1. x_ wird implizit in X konvertiert -> Kopierkonstruktor (ev. elided) 2. Destruktor von guard wird aufgerufen (passiert garantiert nach dem return) 3. return value wird an f gebunden, Lebenszeit verlängert, nichts passiert */ X f2 = a.foo(); // hier Kopie-Guard-Kopie, eine Kopie davon kann elided werden }Dass das return-statement vor den Destruktoren (welche erst am Ende des Blocks aufgerufen werden) ausgeführt wird, sollte klar sein.
-
@ schrieb:
Ist es garantiert, dass das Temporary für den return-Wert *vor* dem Destruktor des Scope-Guards ausgeführt wird?
Ja.
Falls es garantiert ist, bitte einen entsprechenden Verweis auf den Standard.
Darfst du dir selber suchen.
Oder du begnügst dich mit folgender Überlegung:
* Der Returnwert muss kopiert werden bevor das Objekt welches kopiert wird zerstört wird.
* Man kann lokale Variablen zurückgeben.=> Der Returnwert muss kopiert werden bevor lokale Variablen zerstört werden.
Easy.
-
Youka schrieb:
...the expression is evaluated just before the function returns to its caller.
Diese Beschreibung ist somit doch ziemlich genau.
Ich finde die Formulierung insofern schwammig, dass man es auch so lesen könnte als wenn der Zeitpunkt bis zum letztmöglichen Punkt verzögert wird, potenziell auch nach der Zerstörung von lokalen Objekten.
Da habe ich vermutlich aber zu nah an der Maschine gedacht und das return statement mit dem eigentlichen ret gleichgesetzt. Anders gelesen macht es perfekt Sinn, danke.