2016-05-18 10 views
6

Per C++ precedente al 2011, lo standard dice che le enumerazioni possono essere di qualsiasi dimensione, da byte a lunghe lunghe. Ma in pratica sembra che la maggior parte dei compilatori li realizzi, 4 byte.Dimensioni Enum * in pratica *

Quindi, in pratica i compilatori vagamente attuali non li fanno?

E mi sembra di aver bisogno di chiarire che non sto facendo nulla di strano, come enum> 2^31. Solo semplici enumerazioni. E su sistemi a 32 o 64 bit, il mio software non funzionerà su 16 bit!

+7

'int' non è necessariamente 4 byte. – user657267

+1

'enum/* class */MyEnum: unsigned char {...};'. Nel compilatore C99, uno dei miei clienti ha riportato un errore che si è ridotto a un modulo non correlato assumendo la dimensione di enum = sizeof UINT32. –

+1

... e un byte non è necessariamente 8 bit. –

risposta

7

Se un enum era sempre int, allora la seguente sarebbe pericoloso:

enum oops { 
    foo = 32767, 
    bar, /*what am I?*/ 
}; 

Ciò è perché un int può essere piccolo come 16 bit (e che è ancora sorprendentemente comune). Su un sistema con 32 bit int, è possibile impostare foo = 2147483647 e il compilatore sicuramente lo non sarebbe scegliere uno int come tipo sottostante.

Quindi i bod corti del linguaggio C++ specificano che il tipo integrale deve essere in grado di rappresentare i valori dati e un compilatore è libero di sceglierne uno appropriato. Dato che int è spesso considerato come il tipo nativo della macchina, è spesso una scelta sensata.

Se si desidera conoscere il tipo sottostante di uno enum, allora lo fornisce std::underlying_type.

+0

'e il tuo compilatore non sceglierebbe di certo un int come il tipo sottostante. MSVC sceglie' int' per rappresentare 'long long', risultando in troncamento. * * * Dà un avvertimento ma personalmente credo che dovrebbe essere un errore difficile. –

7

Vediamo su qualsiasi compilatore moderno:

#include <iostream> 
#include <limits> 

enum MySmallSmall { 
    SmallValue = 0, 
}; 

enum MyLongLong { 
    LongValue = std::numeric_limits<long long>::max() 
}; 

int main() { 
    std::cout << "sizeof MySmallSmall is " << sizeof(MySmallSmall) << std::endl; 
    std::cout << "sizeof MyLongLong is " << sizeof(MyLongLong) << std::endl; 
    return 0; 
} 

clang e g ++ uscita:

sizeof MySmallSmall è 4

sizeof MyLongLong è 8

Ma per MS Visual Studio entrambi i risultati sono 4 (l'ho controllato usando questo sit e http://rextester.com/l/cpp_online_compiler_visual non si sa quale versione del compilatore è qui)

Quindi non si può fare affidamento sulla dimensione di alcun enum.

+0

Non vedo come questa risposta aggiunge qualcosa.Nella domanda è già stato affermato che il tipo sottostante è definito dall'implementazione. –

+0

Anche MSVC è sbagliato qui. Il valore massimo di 'long long' non può essere contenuto in' int', quindi non dovrebbe nemmeno compilarlo. –

+2

@sleeptightpupper la domanda era "Quindi, in pratica, i compilatori vagamente attuali non li rendono disponibili?" ... C'è un solo modo per rispondere alla domanda di pratica, controllarlo. E tu hai ragione che msvc non segue lo standard. Ma questa è una vita e gli sviluppatori devono adottarla. –

-3

GNU ++ Compiler, è possibile verificare con

#include <iostream> 

enum Tmp : unsigned long long int { 
    foo = 600000000000, 
    bar = 12, 
}; 


int main() { 
    Tmp lol; 
     std::cout << sizeof(lol) << " : " << Tmp::foo << " : " << sizeof(Tmp::foo) << std::endl; 
} 

risposta sarà 8