2015-03-13 12 views
20

Non riesco a vedere perché la dimensione dell'enumerazione è rilevante per il compilatore mentre la dimensione della classe non lo è.Perché deve essere fornita una dimensione di enumerazione quando viene dichiarata inoltrata?

mio esempio di codice:

class A; 
enum E; // must be enum E : int; in order to compile 

void f(const A & param); 
void f(const E & param); 

sto parlando qui di standard di compilatori C++. So che MSVC lo ha lasciato compilare e funziona bene. Quindi la domanda è:

Perché questo non è stato standardizzato?

+0

È anche più cauto di quanto si pensi: penso che msvc forza le enum non registrate a 32 bit. – Yakk

+0

@Yakk lo penso anch'io. Ma perché la dimensione dovrebbe essere rilevante comunque? – nyarlathotep108

+0

Non sono sicuro che sia la dimensione che è rilevante, ma piuttosto, la cosa chiaramente non è la sintassi C++ 03. Invece di una dimensione è possibile utilizzare un'enumerazione con ambito, con una delle parole chiave struct o class. Normali rilevanti: "Una dichiarazione-enum opaca che dichiara un'enumerazione senza ambito non deve omettere l'enum-base." –

risposta

11

Questo è stato standardizzato, proposal 2764: Forward declaration of enumerations (rev. 3) ha consentito la dichiarazione diretta di enumerazione se si specifica il tipo sottostante, mentre prima non era possibile.

Il motivo principale è che quando il tipo sottostante non viene specificato, la dimensione è definita dall'implementazione e può dipendere dai valori dell'enumeratore. Dal progetto C++ 11 sezione standard 7.2[dcl.enum]:

Per un'enumerazione cui tipo sottostante non è fisso, il sottostante tipo è un tipo integrale che può rappresentare tutte le enumeratore Valori definito nell'enumerazione. Se nessun tipo integrale può rappresentare tutti i valori dell'enumeratore , l'enumerazione non è corretta. È definito dall'implementazione il tipo integrale utilizzato come tipo sottostante eccetto per il fatto che il tipo sottostante non deve essere maggiore di int a meno che il valore di un enumeratore non possa rientrare in un int interno o senza segno int. Se l'enumeratore-elenco è vuoto, il tipo sottostante è come se l'enumerazione aveva un solo enumeratore con valore 0.

Quando passare il valore ha senso che non conoscendo il tipo sottostante è un problema, ma perché è un problema quando si tratta di un puntatore o di un riferimento? Questo è importante dal momento che a quanto pare su alcune architetture, char * e int * possono avere dimensioni diverse, come indicato in questo comp.lang.c++ discussion: GCC and forward declaration of enum:

[...] Mentre la maggior parte delle architetture potrebbe non essere un problema, in alcune architetture il puntatore avrà una dimensione diversa, nel caso si tratti di un puntatore char . Quindi finalmente il nostro compilatore immaginario non avrebbe idea di cosa mettere lì per ottenere un ColorsEnum * [...]

Abbiamo la seguente risposta StackOverflow per riferimento, che descrive il caso in cui char* can be larger than int*, che esegue il backup l'affermazione nella discussione di cui sopra.

Alcuni more details on the possible sizes of pointers come char * e void * sono le due eccezioni principali qui e quindi altri puntatori di oggetti non dovrebbero avere gli stessi problemi. Quindi sembra che questo caso finisca per essere unico per le enumerazioni.

+0

I commenti non sono per discussioni estese; questa conversazione è stata [spostata in chat] (http://chat.stackoverflow.com/rooms/73124/discussion-on-answer-by-shafik-yaghmour-why-must-an-enumerations-size-be-provid) . – Taryn

7

È una differenza negli obiettivi di progettazione.

Inoltro che dichiara una classe crea un tipo incompleto che può essere utilizzato opaco nei puntatori/riferimenti. Questa è una proprietà molto utile.

Un tipo di enumerazione incompleto non è utile. Tuttavia essere in grado di dichiarare un enum senza dichiarare quali costanti sono all'interno di quell'enum è utile. La complessità che deriva da un tipo di enumerazione incompleta può essere evitata richiedendo che la dimensione sia specificata.

Quindi la mia ipotesi migliore è che gli implementatori di compilatori fossero tenuti a mente quando questa funzione è stata progettata e il comitato ha rilevato che la maggiore complessità delle enumerazioni incomplete non valeva i benefici.

+0

"La complessità che deriva da un tipo di enumerazione incompleta può essere evitata richiedendo che la dimensione sia specificata." Può essere così (anche se ne dubito) ma è del tutto irrilevante, dal momento che non è un requisito che una dimensione è specificata. Il requisito è che il tipo enum abbia un ambito o abbia una dimensione specificata, o entrambi. –

+0

@ Cheersandhth.-Alf Ovviamente mi riferisco a specificare le dimensioni quando non può essere dedotto. Un tipo enum con scope ha una dimensione predefinita di 'int'. – orlp

+1

Cosa succede se si desidera un puntatore a un enum? O riferimento? Questo non ha bisogno di informazioni sulle dimensioni, solo il fatto che il nome si riferisce a un tipo. – Yakk

Problemi correlati