Zuweisung Rückgabewert vor Destruktoraufruf
-
Hallo zusammen,
Ist durch den Standard garantiert, dass zuerst der Rückgabewert zugewiesen wird bzw. der Copy-Constructor aufgerufen wird, bevor der Destruktor für die Objekte im äußeren Scope aufgerufen wird?
#include <mutex> #include <iostream> struct bar { bar(){ std::cout << "create"<< std::endl; } bar(const bar& b){ std::cout << "copy"<< std::endl; } bar& operator=(const bar& b){ std::cout << "copy"<< std::endl; return *this; } }; struct debug_mutex{ void lock(){ std::cout << "lock" << std::endl; } void unlock(){ std::cout << "unlock" << std::endl; } bool try_lock(){ std::cout << "try_lock" << std::endl; return true; } }; struct foo{ bar foobar(){ std::lock_guard<debug_mutex> lock_it(_mutex); return _b; } bar _b; debug_mutex _mutex; }; int main(){ foo f; bar b(f.foobar()); }Ist sogar garantiert, dass erst die Zuweisung gemacht wird und dann der Destructor für alle verbleibenden zu zerstörenden Objekte aufgerufen wird?
bar foobar(int i){ if(i == 0){ std::lock_guard<debug_mutex> lock_it(_mutex); return _b; } return _b; }Also mein gcc 4.5 macht es jedenfalls so. Aber ist es auch garantiert?
Gruß,
XSpille
-
Dir ist schon klar, dass der Aufruf der Funktion
std::string g() { std::string a; return a; }dann zu einen Laufzeitfehler führen würde, weil
azerstört wird, bevor die Zuweisung gemacht wird? Also: Klar.Edit: Ich glaube, ich missverstehe, was du mit "äußerer Scope" meinst.
-
Sone schrieb:
Dir ist schon klar, dass der Aufruf der Funktion
std::string g() { std::string a; return a; }dann zu einen Laufzeitfehler führen würde, weil
azerstört wird, bevor die Zuweisung gemacht wird?Diese Aussage wage ich mal zu bezweifeln...

In dem Code, wird das zurückgelieferte Objekt erst zugewiesen und dann zerstört

-
XSpille schrieb:
Sone schrieb:
Dir ist schon klar, dass der Aufruf der Funktion
std::string g() { std::string a; return a; }dann zu einen Laufzeitfehler führen würde, weil
azerstört wird, bevor die Zuweisung gemacht wird?Diese Aussage wage ich mal zu bezweifeln...

In dem Code, wird das zurückgelieferte Objekt erst zugewiesen und dann zerstört

Nein! Du hast mich total missverstanden. Wenn der Rückgabewert danach zugewiesen werden würde, dann... würde das zu einem Laufzeitfehler führen.
Das heißt: Auf jeden Fall wird zuerst zugewiesen und dann werden erst die Destruktoren für die Funktionslokalen Objekte aufgerufen.
-
@XSpille
Ja, ist garantiert.
Die Return-Anweisung steht ja noch klar innerhalb des Scopes der Funktion (bzw. des ifs), und referenziert in diesem Scope irgendwelche Dinge (Member, was auch immer).
Der Zugriff auf diese Dinge, das konstruieren des Returnwerts etc. muss also auch in diesem Scope erfolgen.Das nötige Standardese dazu kann ich dir aber nicht liefern, müsstest du ggf. selbst nachschlagen (oder warten bis einer der Standardauswendigkenner hier reinschneit).
-
hustbaer schrieb:
@XSpille
Ja, ist garantiert.Danke hustbaer!

Diese Aussage reicht mir völlig@Sone:
Jetzt verstehe ich, was du meinst
DAnke euch beiden
-
XSpille schrieb:
Ist durch den Standard garantiert, dass zuerst der Rückgabewert zugewiesen wird bzw. der Copy-Constructor aufgerufen wird, bevor der Destruktor für die Objekte im äußeren Scope aufgerufen wird?
Ich bin mir nicht sicher was genau du mit "äußerem Scope" meinst. Es ist afaik garantiert, dass dein _b in den Rückgabewert kopiert wird bevor der lock_guard aufgeht, falls du das meinst. Wenn du allerdings mit den Rückgabewert dann irgendwas machen würdest, sodass nochmal kopiert werden würde, würde diese Kopie potentiell (dem Compiler wäre es erlaubt, die Kopie wegzulassen, was so ziemlich jeder aktuelle Compiler tun sollte, aber garantiert ist das nicht) natürlich außerhalb des Scope, aus dem das return kam, stattfinden.
XSpille schrieb:
Ist sogar garantiert, dass erst die Zuweisung gemacht wird und dann der Destructor für alle verbleibenden zu zerstörenden Objekte aufgerufen wird?
Was genau für eine Zuweisung meinst du, ich seh da nirgendwo eine!?