2011-12-16 11 views
6

Quando sto leggendo lo standard C++, sembra che il seguente codice sia perfettamente a posto secondo lo standard.Perché è OK passare all'ambito di un oggetto di tipo scalare senza un inizializzatore?

int main() { 
    goto lol; 
    { 
     int x; 
lol: 
     cout << x << endl; 
    } 
} 

// OK 

[n3290: 6,7/3]: è possibile trasferire in un blocco, ma non in modo che aggira le dichiarazioni con l'inizializzazione. Un programma che salta da un punto in cui una variabile con durata di memorizzazione automatica è non portata a un punto in cui è portata è mal formata meno che la variabile ha scalari tipo, tipo di classe con un banale predefinito costruttore e un distruttore banale, una versione cv-qualificata di uno dei tipi o un array di uno dei tipi precedenti ed è dichiarato senza un inizializzatore.

Perché dovrebbe funzionare? Non è ancora pericoloso saltare oltre la sua definizione e usare un indefinito x? E perché l'esistenza di un inizializzatore dovrebbe fare la differenza?

risposta

7

In ogni caso, usereste uno x non inizializzato, dal momento che lo int x; è non inizializzato come sarà. L'esistenza di un inizializzatore fa ovviamente la differenza, perché lo salteresti. int x = 5; ad esempio inizializza x, quindi farebbe la differenza se l'avessi saltato sopra o no.

+0

Ma il problema è che, indipendentemente da un inizializzatore, x non è definito perché la sua definizione viene comunque ignorata. Non è vero? –

+0

@EricZ: la definizione si verifica ancora. 'goto' è una cosa runtime, salta solo il comportamento di runtime, come l'inizializzazione. – GManNickG

+0

@GMan, giusto! Grazie;) –

2

Non è ancora pericoloso saltare la sua definizione e utilizzare x non inizializzato?

Ma il x sarebbe comunque non inizializzato, perché è stato dichiarato senza inizializzatore! Quindi lo goto potrebbe saltare le istruzioni di assegnazione che impostano (sort-of-initialize) x, ma non è sorprendente che goto salti le istruzioni di assegnazione; e la dichiarazione di per sé non è in realtà do a meno che non ci sia un inizializzatore.

+1

+1 * la dichiarazione di per sé non fa nulla *. Questo è il punto chiave. Senza un inizializzatore, non viene generato alcun codice. Le regole assicurano che non stai saltando realmente alcun codice. –

+0

@Ernest, sono curioso di sapere come x è stato definito perché la sua definizione è passata? –

+2

Immaginate che un registro del processore libero sia designato per contenere 'x'. Questo è solo contabilità nel compilatore; non c'è nulla di fisicamente nel codice generato che dice "Registrati 17 è ora' x'. " Ora, se 'x' fosse inizializzato, avremmo il codice per impostare il valore del registro - ma come abbiamo detto, non c'è niente di tutto ciò. –

Problemi correlati