2009-04-27 10 views
20

È l'ultima virgola richiesta in una dichiarazione C enum?È richiesta l'ultima virgola in C enum?

cioè la virgola dopo VAL3 richiesto?

enum{Val1, Val2, Val3,} someEnum; 

ci sono eventuali effetti collaterali di lasciarlo in/out

Grazie

+9

In standard C89, l'ultima virgola era esplicitamente vietata. Nel C99, lo permettono. L'effetto collaterale di lasciarlo dentro è che non può essere compilato da rigidi compilatori C89. –

risposta

36

Non necessario. Sezione 6.7.2.2 di C99 elenca la sintassi:

enum-specifier: 
    enum identifieropt { enumerator-list } 
    enum identifieropt { enumerator-list , } 
    enum identifier 
enumerator-list: 
    enumerator 
    enumerator-list , enumerator 
enumerator: 
    enumeration-constant 
    enumeration-constant = constant-expression 

notare i primi due forme di enum-specifier, uno con la virgola finale e una senza.

Un vantaggio che ho visto a usarlo è nelle cose come:

enum { 
    Val1, 
    Val2, 
    Val3, 
} someEnum; 

in cui, se si desidera aggiungere a (per esempio) e Val4Val5, basta copiare e incollare la linea Val3 senza doversi preoccupare di regolare le virgole.

E, come indicato in un commento, può anche essere semplificare i generatori di codice automatici in modo che non debbano avere una gestione speciale per il valore finale. Possono solo emettere ogni valore seguito da una virgola.

Questo può essere paragonato a SQL spesso visto:

select fld1, fld2 from tbl where 1=1 and fld1 > 8 

In tal caso, il where 1=1 è lì solo in modo che non si dispone di mettere un where prima della prima clausola e un and prima ogni successivo. Puoi semplicemente contare sul fatto che lo where è già presente e utilizzare solo and per tutti quelli che aggiungi.

Alcune persone possono pensare che questo puzza di pigrizia e hanno ragione, ma non è necessariamente una cosa negativa :-)

Qualsiasi decente DBMS interrogazione ottimizzatore dovrebbe essere in grado di nudo fuori clausola costante come quella prima di andare a le tabelle del database.

+8

Un altro motivo per cui ho sentito parlare è per il codice generato dalla macchina - un caso di angolo in meno necessario nel generatore di codice. –

1

No, non è necessario e deve essere omessa per il codice chiarezza. La sua presenza/assenza non ha alcun effetto.

+2

Sarebbe molto più preciso dire che una virgola finale non ha valore semantico. La sua assenza può rendere la manutenzione del codice meno conveniente. In che modo l'assenza di una virgola finale rende il codice più chiaro? –

+0

Quando l'ultimo elemento dell'enumerazione è seguito da una parentesi graffa immediatamente mi sembra più chiaro. Suppongo soggettivo. – sharptooth

3

No, non è necessario, anzi, direi che averlo è brutto stile.

4

No, non è necessario. Il motivo è che rende più facile ai fini del codice taglia e incolla, se non è necessario preoccuparsi se la virgola è destinata a essere lì o meno.

3

Come già detto non è richiesto. La ragione per cui è supportata una virgola finale è che (supponendo che gli elementi siano disposti uno su una riga) ti permette di riorganizzare comodamente l'ordine degli elementi in un'enumerazione usando taglia/incolla o trascina/rilascia e ti consente anche di commentare l'ultimo elemento senza produrre un errore di sintassi. Omettere la virgola finale è legale ma perde questi vantaggi di manutenzione del codice.

Avevo dimenticato ma Nick ha perfettamente ragione. Anch'io ho sfruttato la virgola finale con le direttive del compilatore. Senza di esso, il codice condizionale sarebbe stato molto più disordinato e difficile da leggere.

2

È opzionale e utile, se si dice di utilizzare la macro, ad es.

#ifdef _FLAG 
    #define OPTS opt_four, opt_five, 
#else 
    #define OPTS // none 
#endif 
enum { 
    opt_one, 
    opt_two, 
    opt_three, 
    OPTS 
}; 
0

Non è necessario, infatti alcuni compilatori si lamentano se ne aggiungi uno. per esempio Visual Studio 6.
Un uso per la virgola è per la creazione di enumerazioni usando macro c.

#define ELEMENT(x) x, 

enum MyElements { 
    ELEMENT(a) 
    ELEMENT(b) 
    ELEMENT(c) 
}; 

Questo modello è utile se si ci sono diverse cose che devi fare con gli elementi e solo voler definire una volta. Per un esempio più completo di questo si può guardare il codice di libiconv e l'utility iconv.

+0

Questo è male. Perché non usare: "#define ELEMENT (x) x" e poi aggiungi le virgole nell'enum? – nilton

+1

L'idea è che i contenuti dell'enumerazione siano a loro volta un'altra macro: '#define ALL_ELEMENTS (ELEMENT) ELEMENT (a) ELEMENT (b) ELEMENT (c)'. Quindi "#define ELEMENT" per qualsiasi cosa ti serva in un determinato momento, quindi invoca la macro 'ALL_ELEMENTS'. –

14

Come tutti gli altri dicono, la virgola non è richiesta. Ma è nuovo in C99 (non era permesso in C89) e sarà permesso anche nella prossima versione di C++.

Un altra logica è quella di fare la differenza tra un enumeratore "lunghezza" e un enumeratore normale:

enum Items { 
    A, 
    B, 
    C, 
    LENGTH 
}; 

Ora, si può mettere nella vostra linea guida di codifica che l'ultimo elemento nella enumerazione dovrebbe avere una virgola applicato, ma non se è un elemento "Lunghezza" - che indica solo quanti elementi ci sono.

Aiuta anche per la generazione automatica di elementi (utilizzando macro/preprocessori) come spiegano altre risposte.

+3

È un peccato che l'idioma LUNGHEZZA interrompa il controllo automatico della completezza dell'interruttore (enum). –

7

In standard C89, l'ultima virgola non è consentita. Punto.

Era un'estensione comune consentirlo; in particolare, è stato supportato da GCC, ma lo standard lo ha espressamente vietato.

In standard C99, è consentita l'ultima virgola, per simmetria con gli inizializzatori di matrice e struttura, che ha sempre consentito la virgola finale sull'ultimo elemento.

6.7.2.2 specificatori censimento

sintassi

enum-specifier: 
      enum identifieropt { enumerator-list } 
      enum identifieropt { enumerator-list , } 
      enum identifier 

Il vantaggio principale di consentire virgole finali è che permette facile generazione di macchine (sorgente C) codice - non si dispone scrivere un codice di caso speciale per l'ultimo (o, forse, il primo) elemento nell'elenco di inizializzatori. Quindi, programmi come Yacc e Lex, per citarne solo due, possono essere leggermente più semplici.

0

Altre risposte lo menzionano, ma vorrei solo sottolineare che la virgola finale non è consentita negli standard C89 e C++ conformi agli standard, il che lo rende un problema di portabilità con i compilatori vecchi o non comuni. Ecco un link utile che spiega questo e molti altri problemi C/C++: http://david.tribble.com/text/cdiffs.htm#C99-enum-decl

1

L'ultima virgola finale non è richiesta.

preferisco le virgole finali per due motivi:

  1. Clean git diffs.
  2. Facile modifica in editor con comandi basati su riga (ad esempio Vim's dd).