2016-05-02 51 views
17

Questo è un seguito alla mia domanda precedente What is the order of destruction of function arguments? perché ho confuso accidentalmente argomenti con parametri. Grazie a Columbo e T.C. per liberarmi dalla confusione terminologica nei commenti di quella domanda.Qual è l'ordine di distruzione dei parametri di funzione?

Se il corpo di qualche funzione f con i parametri p_1, ..., p_n di tipi T_1, ..., T_n tiri rispettivamente un'eccezione, finiture o ritorni, in che ordine sono i parametri distrutti e perché? Si prega di fornire un riferimento allo standard, se possibile.

Esempi:

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

Non credo che il lancio di un'eccezione faccia una grande differenza in merito all'ordine di valutazione. –

risposta

14

Il punto temporale in cui vengono distrutte parametri è unspecified:

CWG deciso di renderlo specificato se oggetti parametro vengono distrutti immediatamente successivo alla chiamata o al fine dell'espressione completa a cui appartiene la chiamata.

L'ordine in cui sono costruiti i parametri è specificato pure, ma perché i parametri funzionali hanno portata blocco, anche se il loro ordine di costruzione non è specificato, distruzione è nell'ordine inverso di costruzione. Per esempio. considerare

#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 << "#"); 
} 

stampe 10#~0~1with GCC e 01#~1~0 con Clang; costruiscono i parametri in ordini diversi, ma entrambi distruggono nell'ordine inverso di costruzione, alla fine della piena espressione in cui si verifica la chiamata (piuttosto che subito dopo il ritorno al chiamante). VC++ prints 10~0~1#.

+2

Esiste la necessità che l'ordine di distruzione sia il contrario dell'ordine di costruzione? –

+0

@ M.M Immagino che anche se non ci fosse, sarebbe implicitamente necessario poiché altrimenti potrebbe facilmente rovinare cose con RAII, come se si trattasse di un deadlock con due blocchi trattenuti e non rilasciati nell'ordine corretto. – Mehrdad

+0

@ M.M Probabilmente è il caso nella pratica. Tuttavia, i parametri non hanno durata di archiviazione automatica e non sono temporanei, quindi non riesco a trovare alcuna istruzione formale (e non vedo perché sarebbe utile). – Columbo