Sì, la dichiarazione è perfettamente valida e portabile sia in C che in C++.
Sia C e C++, questo:
enum State {DISABLED=0, ENABLED=!DISABLED};
è esattamente equivalente a questo:
enum State {DISABLED=0, ENABLED=1};
ea tal:
enum State {DISABLED, ENABLED};
ma per sottilmente diverse ragioni.
In C, il !
operatore unario produce un risultato di tipo int
, con valore sia 0
(se l'operando è diverso da 0
) o 1
(se l'operando è uguale a 0
). !x
è equivalente a x == 0
. (Qualsiasi valore diverso da zero viene considerato true se utilizzato come condizione, ma gli operatori !
e ==
, tra gli altri, producono sempre un risultato esattamente uguale a 0
o 1
). Le costanti di enumerazione sono sempre di tipo int
; se viene specificato un valore, viene convertito in int
se necessario.
(C tipo _Bool
aggiunto nello standard 1999 ma tutti gli operatori che producono logicamente valori "booleani" tuttavia risultati di tipo int
.)
In C++, il risultato della !
operatore unario è di tipo bool
. Il risultato è false
o true
dove l'operatore !
di C restituisce 0
o 1
, rispettivamente. Come in C, se viene specificato un valore, viene convertito secondo necessità; i valori bool
false
e true
convertiti in 0
e 1
, rispettivamente.
In C, le costanti di enumerazione sono sempre di tipo int
. In C++, sono del tipo di enumerazione, in questo caso enum State
.
Il riferimento a una costante di enumerazione precedente all'interno della stessa dichiarazione di tipo è legale. Ogni costante di enumerazione diventa visibile dopo la sua dichiarazione.
Per quanto riguarda qualcosa di simile:
enum bool { false = 0, true = !false);
essere più chiaro di
enum bool { false = 0, true = 1 };
(in C, sarebbe illegale in C++), ho rispettosamente in disaccordo. La costante 1
è perfettamente chiara per chiunque abbia familiarità con C. Riscrivendolo come !false
non è utile.Infatti, quando <stdbool.h>
non è disponibile (qualcosa che è raro in questi giorni), ho usato:
typedef enum { false, true } bool;
Il fatto che false
e true
sarà dato loro valori corretti è IMHO sufficientemente evidente.
Per quanto riguarda il motivo per cui C99 non ha utilizzato una definizione simile a enum
, ho il sospetto che sia perché ogni tipo di enumerazione è compatibile con un tipo di intero definito dall'implementazione. (Per gcc, di solito è unsigned int
o int
.) Il comitato voleva che _Bool
fosse un tipo distinto con un grado di conversione inferiore a qualsiasi altro tipo intero. (E non potevano rendere bool
una parola chiave senza rompere il codice esistente.)
conforme ANSI? Questa è una frase che non ho sentito da un po '. –
@DawidPi C e C++ sono lingue diverse, e problemi delicati come questo praticamente non ottengono mai una buona risposta che copra entrambe le lingue allo stesso tempo. Se vuoi davvero conoscere entrambe le lingue, per favore chiedi loro come domande separate. – hvd
@AlanStokes Se hai un problema con una modifica che ho fatto esplicitamente spiegando nei commenti, mi sembra abbastanza scortese di ripristinarlo senza alcun commento. Non voglio entrare in una guerra di chiusura su questo, ma per quanto mi riguarda, questa domanda era troppo ampia nel suo stato originale, e se hai intenzione di ostacolare i tentativi di metterlo in forma, bene , Voterò solo per chiudere. (Il che ovviamente non significa affatto che finirà per chiudere). – hvd