2009-07-12 8 views
54

Penso che sto diventando cieco, perché non riesco a capire dove l'errore di sintassi è in questo codice:Posso dichiarare variabili all'interno di un'istruzione switch Objective-C?

if(cell == nil) { 
    titledCell = [ [ [ TitledCell alloc ] initWithFrame:CGRectZero 
     reuseIdentifier:CellIdentifier ] autorelease 
    ]; 

    switch(cellNumber) { 
     case 1: 
      NSString *viewDataKey = @"Name"; 
etc... 

Quando provo a compilarlo, sto ricevendo un errore : errore di sintassi prima del token '*' sull'ultima riga.

Ci scusiamo per una domanda di base, ma cosa mi manca?

+1

Che tipo di variabile è CellNumber? L'istruzione switch è da C, quindi l'uso dei tipi Objective-C può farlo scattare. –

+1

C supporta solo oggetti di tipo integrale per 'switch/case', e mi aspetterei un messaggio di errore diverso se questo fosse il problema qui. – ephemient

+0

Objective-C segue C99 (e C++) e ti permette di dichiarare variabili ovunque, o puoi farlo solo all'inizio di un blocco?Se sei costretto a dichiararli all'inizio di un blocco, allora potresti correggere il tuo errore di sintassi inserendo un '' {''dopo il' ':'' di ''case 1:'' e un matching ''} "prima della fine del caso. –

risposta

66

Non ho un opportuno compilatore Objective-C a portata di mano, ma finché i costrutti C sono identici:

switch { … } ti dà uno ambito a livello di blocco, non uno per ogni case. La dichiarazione di una variabile diversa da quella iniziale dell'ambito è illegale e all'interno di uno switch è in particolare pericoloso perché l'inizializzazione può essere saltata.

Una delle seguenti soluzioni risolve il problema?

NSString *viewDataKey; 
switch (cellNumber) { 
    case 1: 
     viewDataKey = @"Name"; 
    … 
} 

switch (cellNumber) { 
    case 1: { 
     NSString *viewDataKey = @"Name"; 
     … 
    } 
    … 
} 
+2

wrt/'Dichiarare una variabile in un punto diverso dall'inizio dell'oscilloscopio è illegale'. Questo non è vero nel C99. C99 consente entrambi e definisce la semantica di ciò che accade quando "il controllo supera una dichiarazione" e il valore di tale dichiarazione in questi casi. – johne

+0

Ho dimenticato di indicare quale opzione ha risolto il problema, oops. Ho usato quello in alto per risolvere il problema - non penso di aver provato il secondo suggerimento, il che è un peccato, perché voi ragazzi sembrate avere una bella discussione! – JoBu1324

+0

Ulteriori dettagli sul perché questi funzionano in http://stackoverflow.com/questions/1231198 –

1

Potrebbe non essere valido dichiarare una variabile all'interno di un blocco di interruttori?

+0

Come ho osservato sulla risposta di Chuck: 'switch (0) {int i; } 'è C89 valido, e Objective-C è un vero superset di C (a differenza di C++), quindi tutto legale in C (modulo rubato identificatori) è legale in Objective-C. – ephemient

20

Non si può dichiarare una variabile all'inizio di un'istruzione case. Crea un caso di prova che sia semplicemente costituito da quello e otterrai lo stesso errore.

Non ha a che fare con le variabili dichiarate nel mezzo di un blocco - anche adottando uno standard che consente a GCC di non accettare una dichiarazione all'inizio di un'istruzione case. Sembra che GCC veda l'etichetta del caso come parte della linea e quindi non consentirà una dichiarazione lì.

Una soluzione semplice consiste semplicemente nel mettere un punto e virgola all'inizio del caso in modo che la dichiarazione non sia all'inizio.

+1

False. 'switch (0) {int i; } 'compila perfettamente anche in C89. – ephemient

+0

Non falso. Ho appena eseguito il tuo esempio dal post di Aragorn tramite GCC e ho ottenuto lo stesso errore. – Chuck

+0

Sto affermando che "non posso dichiarare una variabile in un'istruzione case" è falso. Prova a dare a GCC il piccolo esempio nel mio precedente commento. – ephemient

4

In C è possibile dichiarare le variabili solo all'inizio di un blocco prima di qualsiasi dichiarazione non dichiarata.

{ 
    /* you can declare variables here */ 

    /* block statements */ 

    /* You can't declare variables here */ 
} 

In C++ è possibile dichiarare le variabili in qualsiasi posizione.

+0

'switch (1) {caso 0: int i = 1; rompere; default:/* wtf è io? * /; } 'Anche se puoi dichiarare variabili ovunque, all'interno di un' switch' è * pericoloso *. – ephemient

+0

con Visual Studio 2008 che compila un file c. è -> errore C2143: errore di sintassi: mancante ';' prima di 'digitare' =) – Aragorn

+0

Ignorare gli inizializzatori in C++ è ancora più pericoloso rispetto a C e MSVC è più un compilatore C++ che un compilatore C. Non sono sorpreso che non gli piaccia questa roba. – ephemient

0

Come risolvere l'avvertimento:

1.Insert uno ; nella prima riga del blocco caso

codici 2.Put all'interno delle parentesi

1

È possibile creare una variabile all'interno di un'istruzione switch ma dovrai crearlo all'interno di un blocco in modo da definire l'ambito di tale variabile.

Esempio:

switch(number){ 

    case 1: 
     { 
      // Create object here 
      // object is defined only for the scope of this block 
     } 
     break; 
    case 2: 
     { 
      // etc. 
     } 
     break; 
    default: 
     break; 

} 
+0

Questa è una nuova risposta a una domanda molto vecchia con una risposta accettata. Che cosa fornisce la tua risposta che gli altri no? – JAL

+0

Questo è stato pensato per essere un'alternativa alla prima dichiarazione switch presentata nella risposta accettata. Al momento della pubblicazione non avevo notato la parentesi in linea con la dichiarazione del caso nella seconda istruzione switch fornita. – egarlock

Problemi correlati