2016-05-02 18 views
17

Dies ist ein Follow-up zu meiner vorherigen Frage What is the order of destruction of function arguments?, weil ich versehentlich Argumente mit Parametern verwechselt. Dank an Columbo und T.C. um mich in den Kommentaren dieser Frage von terminologischer Verwirrung zu befreien.Was ist die Reihenfolge der Zerstörung von Funktionsparametern?

Wenn der Körper einer Funktion f mit Parametern p_1, ..., p_n von Typen T_1, ..., T_n wirft jeweils eine Ausnahme, beendet oder zurückgibt, in welcher Reihenfolge die Parameter werden zerstört und warum? Bitte geben Sie wenn möglich einen Hinweis auf den Standard an.

Beispiele:

template <typename ... Args> 
void f(Args ... params) {} // in what order are params destroyed? 

void f(T1 p1, T2 p2, T3 p3) {} // in what order are p1, p2 and p3 destroyed? 
+2

Ich denke nicht, eine Ausnahme zu werfen, macht einen großen Unterschied in Bezug auf die Bewertungsreihenfolge. –

Antwort

14

Der genaue Zeitpunkt, zu welchem ​​Parameter zerstört werden, ist unspecified:

CWG entschieden, es nicht spezifiziert zu treffen, ob sich nach dem Anruf sofort Parameterobjekten zerstört oder im Ende des vollständigen Ausdrucks, zu dem der Anruf gehört.

Die Reihenfolge, in der Parameter aufgebaut werden, ist auch nicht spezifiziert, sondern weil Funktionsparameter Block Umfang haben, obwohl ihre Reihenfolge der Konstruktion nicht näher bezeichnet ist, ist Zerstörung in der umgekehrten Reihenfolge des Aufbaus. Z.B. betrachten

#include <iostream> 

struct A { 
    int i; 
    A(int i) : i(i) {std::cout << i;} 
    ~A() {std::cout << '~' << i;} 
}; 

void f(A, A) {} 

int main() { 
    (f(0, 1), std::cout << "#"); 
} 

druckt 10#~0~1with GCC und 01#~1~0 mit Clang; sie konstruieren Parameter in verschiedenen Ordnungen, aber beide zerstören in der umgekehrten Reihenfolge der Konstruktion, am Ende des Vollausdrucks tritt der Aufruf auf (und nicht gleich nach dem Zurückkehren zum Aufrufer). VC++ prints 10~0~1#.

+2

Gibt es eine Anforderung, dass die Reihenfolge der Zerstörung die umgekehrte Reihenfolge der Konstruktion ist? –

+0

@ M.M Ich stelle mir vor, selbst wenn es nicht wäre, wäre es implizit notwendig, da es ansonsten leicht mit RAII Dinge vermasseln könnte, wie zum Beispiel einen Deadlock mit zwei Sperren, die gehalten und nicht in der richtigen Reihenfolge freigegeben werden. – Mehrdad

+0

@ M.M Das ist wahrscheinlich in der Praxis der Fall. Allerdings haben Parameter keine automatische Speicherdauer und sind keine Provisorien, daher kann ich keine formale Aussage finden (und ich sehe nicht, warum es hilfreich wäre). – Columbo