2010-07-05 6 views
37

Si consideri il seguente codice:Uscire da un blocco: vengono chiamati i distruttori?

void foo() 
{ 
    { 
     CSomeClass bar; 

     // Some code here... 

     goto label; 

     // and here... 
    } 

label: 
    // and here... 
} 

Sarà il distruttore della barra di essere chiamato?

+0

Perché hai bisogno di sapere questo? 'goto' ha senso nel codice generato, ma lì puoi e dovresti comunque evitare oggetti con i distruttori. – MSalters

+13

@MSalters: questo non rende assolutamente necessario, perché dovresti evitare gli oggetti con i distruttori? –

+1

@Viktor: Mi permetta di espandere la seconda parte della frase: _In codice generato_, è possibile e dovrebbe comunque evitare oggetti con i distruttori. L'uso canonico di 'goto' è nel codice FSM generato. Qui i salti si verificano avanti e indietro, senza riguardo per gli stati del codice di stato che si trovano proprio nel mezzo. Gli stati FSM semplicemente non sono lineari, ma il codice C++ deve essere. – MSalters

risposta

52

L'++ standard C dice:

all'uscita da un campo di applicazione (per quanto compiuta), distruttori (12.4) sono chiamata per tutti gli oggetti costruiti con la durata automatica stoccaggio (3.7.2) (dal nome o oggetti o provvisori) dichiarati in tale ambito, in l'ordine inverso della loro dichiarazione .

Quindi la risposta è "sì".

+0

Grazie. Questo è quello di cui avevo bisogno. –

9

1) Sì. 2) Non farlo.

Elaborazione: concettualmente, questo non è diverso dal lasciare un ciclo tramite uno break. goto, tuttavia, è fortemente, fortemente scoraggiato. Non è quasi mai necessario usare goto e qualsiasi uso dovrebbe essere esaminato per scoprire cosa sta succedendo.

+0

Risposta perfetta. – Mizipzor

+1

2) lo fai quando esci effettivamente da loop. –

+14

In realtà, goto ha senso in alcune circostanze. –

21

Sì, saranno chiamati.

Aggiornamento: (.. Va bene per fare questo, goto non è peggiore di generare eccezioni fittizi o utilizzando Caccio/IFS di uscire cose Un semplice goto all'interno di una funzione non rendono spaghetti code)

+7

+1 per negare lo studente egoista che sentiva il bisogno di downvotare perché pensano che i gotos siano malvagi. Gotos ha usi validi, persone, indipendentemente da ciò che i tuoi professori ti hanno detto. – KevenK

+2

"va bene fare questo, gotos non è peggio che lanciare eccezioni fittizie o usare bool/if per uscire dalle cose" Lanciare un'eccezione fittizia è un modo terribile di fare questo (lanciare eccezioni è generalmente estremamente costoso) e se è tra quello e il gotos, preferirei decisamente il gotos. Tuttavia, scrivere le funzioni per questi casi è sicuramente il modo migliore per andare. – stinky472

+1

@KevinK - Gotos può avere usi validi in teoria, ma sono estremamente rari nella pratica. Direi che se sembra che tu debba usare un goto, la situazione merita almeno un attento esame. E per gli sviluppatori principianti, suggerirei di evitarli è una buona disciplina da imparare. – jwismar

4

Sì, come dicono tutti gli altri. C++ specifica/incarica questo.

Ma solo per aggiungere che, per completezza: se il vostro goto utilizza il computed- goto estensione trovato in alcuni compilatori - gcc, clang, forse altri ma non compreso MSVC scorso ho saputo - se il il distruttore dell'oggetto verrà chiamato è piuttosto confuso. Quando un goto si sposta su una singola posizione, è molto chiaro che cosa devono essere chiamati i distruttori prima del trasferimento del flusso di controllo. Ma con uno goto calcolato, potrebbe essere necessario chiamare dinamicamente diversi distruttori per dare la semantica "attesa". Non sono sicuro di cosa facciano i compilatori che implementano questa estensione, in quei casi. La mia memoria dall'incontrare questo è che clang avverte quando un computer calcolato - goto potrebbe lasciare un ambito con un oggetto con un distruttore non trival, sostenendo che il distruttore non verrà chiamato. In alcuni casi potrebbe andare bene, in altri no. Non so a priori cosa fanno gli altri compilatori. Basta essere consapevoli del problema se si desidera utilizzare i computati goto s in concerto con oggetti con distruttori non banali.

+0

Grazie. Io uso solo goto calcolato da C, e in situazioni molto rare. –