2016-05-18 15 views
6

Dla C++ przed rokiem 2011 standard podaje, że wyliczenia mogą mieć dowolny rozmiar, od bajtu do długiego. Ale w praktyce wygląda na to, że większość kompilatorów tworzy je jako 4-bajtowe.Rozmiar wymieniacza * w praktyce *

Tak, w praktyce zrobić jakieś mało aktualne kompilatory nie zrobić ich ints?

I wydaje mi się, że muszę wyjaśnić, że nie robię nic dziwnego, jak wyrazy> 2^31. Po prostu proste wyliczenia. A w systemach 32- lub 64-bitowych moje oprogramowanie nie będzie działać na 16 bitach!

+7

'int' niekoniecznie jest 4 bajty. – user657267

+1

'enum/* class */MyEnum: unsigned char {...};'. W kompilatorze C99 jeden z moich klientów zgłosił błąd, który sprowadził się do niepowiązanego modułu przyjmującego rozmiar enum = sizeof UINT32. –

+1

... a bajt niekoniecznie musi składać się z 8 bitów. –

Odpowiedz

7

Jeśli enum był zawsze int, a następnie po byłoby niebezpieczne:

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

Dzieje się tak dlatego int może być tak mała jak 16 bitów (i jest w dalszym ciągu zaskakująco wspólny). W systemie z 32-bitowym int można ustawić foo = 2147483647, a Twój kompilator z pewnością nie będzie miał wartości , wybierając typ int.

Więc sprytne bod C++ określa, że ​​podstawowy typ enum musi być w stanie reprezentować podane wartości, a kompilator może wybrać odpowiedni. Biorąc pod uwagę, że int jest często uważany za typ natywny urządzenia, często jest to rozsądny wybór.

Jeśli chcesz poznać podstawowy rodzaj modelu enum, to zapewnia to std::underlying_type.

+0

'a twój kompilator z pewnością nie wybrałby typu int jako typ podstawowy." MSVC wybiera opcję 'int' do reprezentowania' long long', powodując obcięcie. To * powoduje * ostrzeżenie, ale osobiście uważam, że powinien to być trudny błąd. –

7

Zobaczmy to na każdej nowoczesnej kompilatora:

#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; 
} 

dzyń i g ++ wyjściowe:

sizeof MySmallSmall jest 4

sizeof MyLongLong jest 8

Ale dla MS Visual Studio oba wyniki to 4 (sprawdziłem to używając tego sit e http://rextester.com/l/cpp_online_compiler_visual nie wiesz, jaka jest tutaj wersja kompilatora)

Nie można polegać na rozmiarze dowolnego wyliczenia.

+0

Nie widzę, jak ta odpowiedź dodaje coś.W pytaniu zadeklarowano już, że typ bazowy jest definiowany przez implementację. –

+0

Również tutaj MSVC jest błędne. Maksymalna wartość 'long long' nie mieści się w' int', więc nie powinna się nawet kompilować. –

+2

@sleeptightpupper pytanie brzmiało: "Czy w praktyce jakieś niejasno obecne kompilatory nie sprawiają, że są one ints?" ... Jest tylko jeden sposób na odpowiedź na pytanie praktyczne, sprawdź to. Masz rację, że msvc nie spełnia standardu. Ale to jest życie i programiści muszą się do niego dostosować. –

-3

GNU ++ kompilator, można przetestować go z

#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; 
} 

Odpowiedź będzie 8

Powiązane problemy