2016-05-18 4 views
6

Для C++ до 2011 года стандарт говорит, что перечисления могут быть любого размера, от байта до долгого. Но на практике большинство компиляторов делают их ints, 4 байта.Enum Размер * на практике *

Итак, на практике делать какие-либо смутные текущие компиляторы, не делать их ints?

И мне, кажется, нужно уточнить, что я не делаю ничего странного, как перечисления> 2^31. Просто простые перечисления. А на 32 или 64-битных системах мое программное обеспечение не будет работать на 16 бит!

+7

'int' это не обязательно 4 байта. – user657267

+1

'enum/* class */MyEnum: unsigned char {...};'. В компиляторе C99 один из моих клиентов сообщил об ошибке, которая сводилась к несвязанному модулю, предполагая размер enum = sizeof UINT32. –

+1

... и байт не обязательно 8 бит. –

ответ

7

Если enum всегда int было, то следующий будет небезопасно:

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

Это потому, что int может быть столь же мал, как 16 бит (и что до сих пор на удивление часто). В системе с 32-битным int вы можете установить foo = 2147483647, и ваш компилятор, безусловно, не будет выбрать int в качестве базового типа.

Таким образом, умные C++-боты указывают, что базовый интегральный тип enum должен быть способен отображать приведенные значения, а компилятор может выбрать подходящий. Учитывая, что int часто рассматривается как родной тип машины, это часто разумный выбор.

Если вы хотите знать базовый тип enum, то std::underlying_type предоставляет это.

+0

'и ваш компилятор, разумеется, не будет выбирать int как базовый тип. MSVC делает' int' для представления 'long long', что приводит к усечению. Это * дает * предупреждение, но я лично считаю, что это должна быть жесткая ошибка. –

7

Давайте посмотрим это на любой современный компилятор:

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

лязг и г ++ выход:

SizeOf MySmallSmall является 4

SIZEOF MyLongLong является 8

Но для MS Visual Studio оба результата: 4 (я проверил его, используя этот сит e http://rextester.com/l/cpp_online_compiler_visual не уверен, что версия для компилятора здесь)

Таким образом, вы не можете полагаться на sizeof любого перечисления.

+0

Я не вижу, как этот ответ добавляет что-либо.В вопросе уже говорилось, что базовый тип определяется реализацией. –

+0

Также здесь находится MSVC. Максимальное значение 'long long' не может вписываться в' int', поэтому его даже не нужно компилировать. –

+2

@sleeptightpupper вопрос был «Итак, на практике какие-то неопределенные текущие компиляторы не делают их ints?» ... Существует только один способ ответить на практический вопрос, проверьте его. И вы правы, что msvc не соответствует стандарту. Но это жизнь, и разработчики должны ее принять. –

-3

++ компилятор GNU, вы можете проверить его с

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

Ответ будет 8