Я создаю набор значений перечисления, но мне нужно, чтобы каждое значение перечисления было шириной 64 бита. Если я правильно помню, enum обычно имеет тот же размер, что и int; но я думал, что где-то читал, что (по крайней мере, в GCC) компилятор может сделать перечисление любой ширины, которая им нужна для хранения своих значений. Итак, возможно ли иметь перечисление шириной 64 бита?
@jokoon: Честно говоря, я больше не помню. Думаю, я хотел, чтобы перечисления содержали значения больше 2 ^ 32-1.
Один из вариантов использования - если вам нужно объединение перечисления и указателя.





enum гарантированно будет достаточно большим для хранения значений int. Компилятор может выбрать фактический используемый тип на основе определенных констант перечисления, поэтому он может выбрать меньший тип, если он может представлять определяемые вами значения. Если вам нужны константы перечисления, которые не подходят для int, вам нужно будет использовать для этого расширения, специфичные для компилятора.
Кажется, ваше первое предложение противоречит последнему. Есть ли ограничение, что enum должен быть больше, чем int, или меньше? После ответа @MichaelStum ваше первое предложение должно быть «enum гарантированно вписывается только в значение int».
Как уродливая реализация, чувствительная к реализации на платформах с двумя дополнениями (это все системы в наши дни?), Вы можете заставить перечисление быть таким же большим, как int, убедившись, что оно содержит отрицательные значения. Однако это не рекомендуемый метод.
Этот ответ, по-видимому, предполагает, что размер enum равен int. Ответ Майкла Стума, который ссылается на C99, говорит, что перечисление может быть размером с char.
Первое предложение этого ответа неверно. enum гарантированно будет достаточно большим, чтобы вместить значение самого большого перечислителя в перечислении.
Взято из текущего стандарта C (C99): http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
6.7.2.2 Enumeration specifiers
[...]
Constraints
The expression that defines the value of an enumeration constant shall be an integer constant expression that has a value representable as an int.
[...]
Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined, but shall be capable of representing the values of all the members of the enumeration.
Не то чтобы компиляторы хорошо следовали стандарту, но по сути: если ваше перечисление содержит что-то еще, кроме int, вы находитесь в глубоком «неподдерживаемом поведении», которое может снова укусить вас через год или два.
Обновление: последний общедоступный проект стандарта C (C11): http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1570.pdf содержит те же пункты. Следовательно, этот ответ все еще верен для C11.
имея только это, я думаю, верно следующее: enum {LAST = INT_MAX, LAST1, LAST2}; поэтому LAST2 не может быть представлен в int, но не было выражения, определяющего его.
В реальном PDF он определяет следующее: «Идентификаторы в списке перечислителя объявляются как константы, имеющие тип int [...]». Я пропустил это, чтобы не было слишком многословно.
Примечание: «Целочисленный тип со знаком а или целочисленный тип без знака ан». Не обязательно int. short и long также являются целочисленными типами, и независимо от выбора реализации все значения должны соответствовать («должен может представлять значения всех членов перечисления»).
Примечательно: константа перечисления и перечислимый типэто не то же самое. Первые являются содержимым списка объявлений enum, вторые - фактической переменной. Таким образом, хотя константы перечисления должны быть int, фактическая переменная перечисления может быть другого типа. Это известное несоответствие в стандарте.
Чтобы прояснить точку зрения Лундина: для enum my_enum { my_value }my_value будет иметь тип int, но enum my_enum может иметь тип, определенный реализацией, который должен, по крайней мере, представлять все значения перечисления. Таким образом, my_value может иметь сужающее преобразование в enum my_enum, но гарантированно не переполнится.
armcc предоставляет параметр компилятора --enum_is_int.
Этот ответ более уместен, чем принятый.
Хотя предыдущие ответы верны, некоторые компиляторы могут нарушить стандарт и использовать наименьший тип, который будет содержать все значения.
Пример с GCC (документация в Руководство GCC):
enum ord {
FIRST = 1,
SECOND,
THIRD
} __attribute__ ((__packed__));
STATIC_ASSERT( sizeof(enum ord) == 1 )
На самом деле, насколько я понимаю, это не противоречит стандарту. Как объясняется в ответе Майкла Стума, стандарт позволяет компилятору выбирать фактический тип перечислений, если все значения подходят.
Я работал с компиляторами MacOS C++, которые используют ограниченный диапазон значений в перечислении для хранения их в меньших типах. Не могу вспомнить, был ли это Metrowerks Codewarrior или XCode. Это в рамках стандарта C++. Вы не можете вообще предполагать sizeof (MyEnum) == sizeof (int).
Рассмотрим этот код:
enum value{a,b,c,d,e,f,g,h,i,j,l,m,n};
value s;
cout << sizeof(s) << endl;
На выходе будет 4. Таким образом, независимо от количества элементов, содержащихся в enum, его размер всегда фиксирован.
Ответ Майкла Стума правильный. Это зависит от компилятора. Вы можете попробовать это сами с IAR EWARM. IAR EWARM показывает 1 для вашего примера. Если имеется до 255 элементов, он все еще показывает 1. После добавления 256-го элемента он увеличивается до 2.
Вопрос не в C++.
важные вещи, которые необходимо понять, прежде чем писать больше на C или C++: просто потому, что он компилируется, не означает, что он законен в соответствии со стандартом. Тот факт, что вы получаете данный результат, не означает, что в Стандарте говорится, что вы всегда будете получать или что другие пользователи будут выполнять ваш код. На подобные вопросы нужен ответ, который ссылается на стандартную или определяемую реализацией спецификацию по меньшей мере для данного компилятора / ABI. Простая компиляция и запуск программы и получение одного результата за один день не дает никаких уроков по таким вопросам (и очень мало по чему-либо еще).
У нас нет контроля над размером переменной enum. Это полностью зависит от реализации, и компилятор дает возможность сохранить имя для целого числа с помощью enum, поэтому enum соответствует размеру целого числа.
На языке C размер enum гарантированно равен int. Существует опция времени компиляции (-fshort-enums), чтобы сделать его максимально коротким (это в основном полезно, если значения не превышают 64 КБ). Во время компиляции нет возможности увеличить его размер до 64 бит.
Просто установите последнее значение перечисления на значение, достаточно большое, чтобы сделать его желаемым размером, тогда оно должно быть такого же размера:
enum value{a=0,b,c,d,e,f,g,h,i,j,l,m,n,last=0xFFFFFFFFFFFFFFFF};
Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, как и / или почему он решает проблему, улучшит долгосрочную ценность ответа.
Это неправда. Компиляция вашего примера с помощью gcc 8.4.0: sizeof(a) - 4, а sizeof(last) - 8.
typedef enum {a1 = 0, b1, c1, d1, f1, last1 = 0xFFFFFFFFFFFFFFFF} testing1; typedef enum {a2 = 0, b2, c2, d2, f2, last2 = 0xFFFFFFFF} testing2; размер переменной типа testing1 равен 8, а размер переменной type testing2 равен 4 ..
Так что, если я хорошо понимаю, вам мало 2 ^ 32 перечислений? Или это проблема выравнивания, зачем вам 64, а не 32, мне очень любопытно.