2011-12-08 7 views
16

In C++ è garantito un valore di ritorno prima che le variabili automatiche nella funzione vengano distrutte? Avviso Basket :: get:Valore di ritorno C++ creato prima o dopo la distruzione della var automatica?

class Basket 
{ 
public: 
    // Gift is a struct containing safely copyable things like int or string 
    Gift gift; 
    // Used to protect access and changes to gift 
    Mutex mutex; 

    // Copy gift into present, while locked to be thread safe 
    void put (const Gift & gift) 
    { 
    Lock lock(mutex); // Constructor locks, destructor unlocks mutex 
    this->gift = gift; // Gift assignment operator 
    } 

    // Return a memberwise-copy of gift, tries to be thread safe (but is it?) 
    Gift get() 
    { 
    Lock lock(mutex); // Constructor locks, destructor unlocks mutex 
    return gift;  // Gift copy constructor 
    } 
}; 

ho bisogno Basket :: arrivare a svolgere il suo costruttore di copia Gift (dell'oggetto temperatura restituiti) prima della distruzione dell'oggetto di blocco. Altrimenti l'oggetto regalo che viene restituito può essere corrotto da una chiamata simultanea da mettere.

I miei test mostrano che la copia regalo viene effettivamente creata prima della distruzione della serratura, tuttavia è garantita? In caso contrario, sarà necessario creare un secondo temporaneo all'interno della funzione, ad esempio:

Gift get() 
    { 
    Gift result; 
    { 
     Lock lock(mutex); 
     result = gift; 
    } 
    return result; 
    } 

risposta

12

Sì, la variabile automatica rimarrà portata fino a dopo il ritorno è terminato. Ciò è particolarmente vero se si utilizza un compilatore che ottimizza la return, ad esempio:

Gift get() 
{ 
    Lock lock(mutex); 
    return gift; 
} 

Gift g = basket.get(); 

che sarebbe equivilent a questa sequenza:

Gift g; 
Lock lock(mutex); 
g = Gift(gift); 
~lock(); 

possono essere ottimizzate per agire più come questo:

void get(Gift &ret) 
{ 
    Lock lock(mutex); 
    ret = gift; 
} 

Gift g; 
basket.get(g); 

che sarebbe equivilent a questa sequenza:

Gift g; 
Lock lock(mutex); 
g = gift; 
~lock(); 

In altre parole, è possibile rimuovere un temporaneo durante lo return.

3

È garantito. Il valore di ritorno viene copiato (se necessario) prima che si verifichi la distruzione. Ecco una domanda/risposta simile che fornisce una buona descrizione della sequenza.

Scope and return values in C++

+1

Non esistono registri nello standard C++. (Bene, c'è la parola chiave 'register', ma questo ha perso il suo significato molto tempo fa.) Inoltre, la maggior parte degli oggetti non si adatterebbe in un singolo registro, comunque. – fredoverflow

+0

Se un oggetto locale è stato restituito, quindi sicuro, dovrebbe essere copiato prima che fosse distrutto. Tuttavia, questo è qualcos'altro. Ho restituito un membro dati della classe, quindi la semantica di esattamente quando la copia si verifica sembra diversa. – maxpolk

+0

@maxpolk Si sta restituendo il membro in base al valore. Ci sarà una copia a meno che il compilatore non possa ottimizzarlo per un incarico di riferimento come ha mostrato Remy. Se dovessi restituire un riferimento o un puntatore, il blocco verrebbe comunque distrutto dopo. – AJG85

Problemi correlati