2010-09-21 16 views
5

Nel bilancio switch-case dichiarazione-con-inizializzazione è valido ma dichiarazione-e-poi-assegnazione è permesso. Come mostrato nello snippet di codice seguente.switch-case: dichiarazione-con-inizializzazione e dichiarazione-e-poi-assegnazione

Qual è la differenza tra questi due tipi di inizializzazioni dal lato del compilatore? E perché il primo tipo di inizializzazione è invalido e il secondo tipo è valido.

switch(val) 
{ 
case 0: 
    int newVal = 42; //Invalid 
    break; 
case 1: 
    int newVal2;  //Valid 
    newVal2 = 42; 
    break; 
case 2: 
    break; 
} 
+0

Che compilatore stai usando? – NullUserException

+0

Visual Studio 2008 –

risposta

4

Infatti, nessuno dei due è C++ legale. Non è possibile dichiarare una variabile in un caso interruttore meno che non sia ambito:

switch(val) 
{ 
case 0: 
    { 
    int newVal = 42; // now valid 
    } 
    break; 
case 1: 
    { 
    int newVal2;  // still Valid 
    newVal2 = 42; 
    } 
    break; 
case 2: 
    break; 
} 

Il fatto che il compilatore permette caso 1 è un difetto del vostro compilatore, o, eventualmente, una proroga. Almeno, secondo lo standard.

+0

La dichiarazione di 'int newVal2;' è valida perché non esiste alcun inizializzatore. –

9

In effetti, la regola è che non è possibile passare in un blocco dopo una dichiarazione che ha un'inizializzazione (o ha superato la dichiarazione di una variabile di tipo non POD). Lo standard C++ dice (C++ 03 §6.7):

È possibile trasferire in un blocco, ma non in un modo che ignora le dichiarazioni con l'inizializzazione. Un programma che salta (77) da un punto in cui una variabile locale con durata di archiviazione automatica non è nell'ambito di un punto in cui è nell'ambito di ambito non è formato a meno che la variabile non abbia il tipo POD (3.9) e sia dichiarata senza inizializzatore (8.5).

(*) Il trasferimento dalle condizioni di un'istruzione switch a un'etichetta case è considerato un salto in questo senso.

int newVal = 42; è una dichiarazione che ha un inizializzatore (la parte = 42). Il programma è mal formato poiché se val è 1 o 2, passerai al blocco switch dopo l'inizializzazione.

int newVal2; è anche una dichiarazione; perché int è un tipo POD e la dichiarazione non ha inizializzatore, è possibile saltare oltre questa dichiarazione.

+0

+1: stavo cercando questo ma non sono riuscito a trovarlo nello standard – Chubsdad

+0

OK. È così perché lo standard C++ dice così. Ma ciò che è razionale dietro lo stesso. Perché lo standard dice così. Non è strano che int newVal = 42; non è permesso dove as int newVal; newVal = 42; È permesso? –

+0

@Dahiya: Non è strano; l'inizializzazione e l'assegnazione sono cose diverse (sono _molte_ cose diverse per la maggior parte dei tipi non POD, poiché i costruttori sono quindi coinvolti nell'inizializzazione). Si consideri, ad esempio, se si dispone di un 'std :: string'; se si salta sopra la sua dichiarazione, la variabile è accessibile ma il suo contenuto non è inizializzato perché il suo costruttore non è mai stato chiamato. –