Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.68/88: Рейтинг темы: голосов - 88, средняя оценка - 4.68
0 / 0 / 0
Регистрация: 09.02.2017
Сообщений: 69

Размер перечисления enum

14.05.2017, 22:29. Показов 19164. Ответов 18
Метки enum (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день.

Где-то я вычитал, что размер перечисления не всегда может быть одинаковый.
Из чего вопрос, как зафиксировать размер перечисления, что-бы при запуске на любой машине, при любых других условиях, у моего приложения он всегда был 4 байта?

Заранее благодарю.
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
14.05.2017, 22:29
Ответы с готовыми решениями:

Диапазон перечисления enum и его размер.
Объясните,пожалуйста,точный,на Ваш взгляд,смысл диапазона перечисления enum и есть ли связь размера и диапазона? Точнее: Например,есть...

Правильное применение перечисления enum
Дело в том, что не пойму как работать с перечислением. Мне нужно, чтобы программа принимала данные о 3 сотрудниках ( дата найма на работу,...

Определение перечисления (enum) в другом файле
Доброго времени суток! :) Вот мой вопрос: в классе A мне необходимо использовать перечисление B, но объявление и определение класса...

18
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
14.05.2017, 22:39
Цитата Сообщение от codesurfer Посмотреть сообщение
как зафиксировать размер перечисления
Тебе поможет enum class из C++11.
1
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
14.05.2017, 22:40
Использовать int32_t вместо enum.
Только нафиг оно надо за вычетом сохранения в файл, для которого как раз и можно явно перекастовать все в int32_t?
0
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
14.05.2017, 22:41
Цитата Сообщение от codesurfer Посмотреть сообщение
что-бы при запуске на любой машине
После компиляции размер не изменится "на любой машине, при любых других условиях"
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
14.05.2017, 22:41
Лучший ответ Сообщение было отмечено codesurfer как решение

Решение

Цитата Сообщение от codesurfer Посмотреть сообщение
он всегда был 4 байта?
C++
1
enum sample: int32_t { ololo };
2
14.05.2017, 23:43

Не по теме:

Не успел ответить :(

Цитата Сообщение от codesurfer Посмотреть сообщение
при любых других условиях, у моего приложения он всегда был 4 байта?
А какая вам разница? У вас enum с такого количества значений, что не влазит в 2 байта на некоторых устройствах?

0
0 / 0 / 0
Регистрация: 09.02.2017
Сообщений: 69
15.05.2017, 16:52  [ТС]
Цитата Сообщение от hoggy Посмотреть сообщение
enum sample: int32_t { ololo };
Подскажите, а при каких вообще условиях размер enum может перестать быть равен 4 байта?
Только если это задаётся вручную или может автоматически в зависимости от каких-то факторов (архитектуры, памяти ещё чего-то)?

Заранее благодарю.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
15.05.2017, 18:13
Цитата Сообщение от codesurfer Посмотреть сообщение
Подскажите, а при каких вообще условиях размер enum может перестать быть равен 4 байта?
64-битовая платформа, на которой удобнее и естественнее пользоваться 64-битовыми же числами.
1
284 / 232 / 114
Регистрация: 07.09.2016
Сообщений: 584
15.05.2017, 18:28
это зависит от максимального значения в енуме. например, если максимальное значение влазиет в 8 бит, то и размер может быть восьмибитным. далее в ход вступают разного рода оптимизации и прочие флаги компиляции. размер может быть увеличен или же остаться минимальным из возможных. это если явно не задан тип и не enum class. для enum class вроде как инт по дефолту.
0
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
15.05.2017, 18:35
Цитата Сообщение от DU3 Посмотреть сообщение
это зависит от максимального значения в енуме. например, если максимальное значение влазиет в 8 бит, то и размер может быть восьмибитным. далее в ход вступают разного рода оптимизации и прочие флаги компиляции. размер может быть увеличен или же остаться минимальным из возможных. это если явно не задан тип и не enum class. для enum class вроде как инт по дефолту.
Подскажите ссылку, где говориться, что
C++
1
enum Foo { A };
будет занимать 8 байт, а если увеличить его значения - то больше. Так сказать sizeof будет прыгать туда сюда в зависимости от количества перечислений внутри
1
70 / 70 / 35
Регистрация: 06.07.2016
Сообщений: 415
15.05.2017, 18:39
Цитата Сообщение от DU3 Посмотреть сообщение
это зависит от максимального значения в енуме.
Похоже на правду, вот только на QtCreator по default все равно выдает 4 байта.
Пустой - 4 байта.
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
 
enum empty
{
 
};
 
int main()
{
  std :: cout <<  sizeof (empty) << std :: endl;
}

С константой, которая влезает только в long int - 8 байт.
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
 
enum non_empty
{
  FIRST = 21480000000
};
 
int main()
{
  std :: cout <<  sizeof (non_empty) << std :: endl;
}
1
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
15.05.2017, 18:45
Интересно :
http://rextester.com/LHYB30248 4 4 4 4
http://rextester.com/QMMFM75605 4 4 4 8
http://rextester.com/WDXMA71230 4 4 4 8
1
284 / 232 / 114
Регистрация: 07.09.2016
Сообщений: 584
15.05.2017, 18:58
стандартом не владею. могу сослаться на авторитетный источник
https://www.ozon.ru/context/detail/id/34747131/
Эффективный и современный С++. 42 рекомендации по использованию C++11 и C++14
Раздел 3.4
2
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
15.05.2017, 19:08
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Подскажите ссылку, где говориться
7.2:
If no initializer is specified for the first enumerator, its type is an unspecified signed integral type
...
It is implementation-defined which integral type is used as the underlying type except that the underlying type shall not be larger than int unless the value of an enumerator cannot fit in an int or unsigned int.
Но применимо только для обычных перечислений, но не работает для enum struct, там по-умолчанию всегда int.

Добавлено через 4 минуты
Тут еще стоит учесть то, что если мы как-то проинициализируем значения enum, то он будет иметь тип такой же, как и у инициализирующего выражения.
2
284 / 232 / 114
Регистрация: 07.09.2016
Сообщений: 584
15.05.2017, 19:38
последнее утверждение на счет инициализации спорно. хотя бы потому, что инициализации могут быть разные,
и непонятно в какой из всех возможных надо выбирать. от типа первого это тоже не зависит. вот попытка
затестить это дело:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <type_traits>
 
enum Foo
{
  A = 1,
  B = 2ULL,
  C = 'c'
};
 
enum class Foo2
{
  B2 = 2ULL,
  A2 = 1,
  C2 = 'c'
};
 
enum class Foo3
{
  B3 = 2ULL,
};
 
template <typename T>
void printTraits()
{
  std::cout << "--------------" << std::endl;
  std::cout << sizeof(2ULL) << std::endl;
  std::cout << sizeof(T) << std::endl;
  std::cout << typeid(std::underlying_type_t<T>).name() << std::endl;
}
 
int main()
{
  printTraits<Foo>();
  printTraits<Foo2>();
  printTraits<Foo3>();
  return 0;
}
1
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
15.05.2017, 22:46
DU3, ага, странно все это.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
 
const unsigned long long x = ~0ull;
enum A : unsigned long long {
    A1,
    A2,
    A3 = x
};
 
using namespace std;
int main() {
    cout << typeid(underlying_type<A>::type).name() << endl;
    cout << x << " " << static_cast<unsigned long long>(A::A3) << " " << A::A3 << endl;
}
Вывод:

unsigned __int64
18446744073709551615 18446744073709551615 4294967295

Хрень какая-то, VS2017 насильно кастует элементы enum к unsigned int...
И даже если значения в enum вылезают за пределы int, то он не выбирает более широкий тип - в топку все это =)

Добавлено через 13 минут
Стандарт по этому поводу говорит просто:
f the underlying type is not fixed, the type of each enumerator prior to the closing
brace is determined as follows:
— If an initializer is specified for an enumerator, the constant-expression shall be an integral constant
expression (8.20). If the expression has unscoped enumeration type, the enumerator has the underlying
type of that enumeration type, otherwise it has the same type as the expression.
— If no initializer is specified for the first enumerator, its type is an unspecified signed integral type.
— Otherwise the type of the enumerator is the same as that of the preceding enumerator unless the
incremented value is not representable in that type, in which case the type is an unspecified integral
type sufficient to contain the incremented value. If no such type exists, the program is ill-formed.
Т.е. если мы жестко не задали тип перечисление, то тип каждого в отдельности элемента перечисления определяется либо выражением, которое его инициализирует, либо предыдущим элементом. Получается, что перечисление может состоять в общем случае из элементов различных типов!

Добавлено через 14 секунд
Стандарт по этому поводу говорит просто:
f the underlying type is not fixed, the type of each enumerator prior to the closing
brace is determined as follows:
— If an initializer is specified for an enumerator, the constant-expression shall be an integral constant
expression (8.20). If the expression has unscoped enumeration type, the enumerator has the underlying
type of that enumeration type, otherwise it has the same type as the expression.
— If no initializer is specified for the first enumerator, its type is an unspecified signed integral type.
— Otherwise the type of the enumerator is the same as that of the preceding enumerator unless the
incremented value is not representable in that type, in which case the type is an unspecified integral
type sufficient to contain the incremented value. If no such type exists, the program is ill-formed.
Т.е. если мы жестко не задали тип перечисление, то тип каждого в отдельности элемента перечисления определяется либо выражением, которое его инициализирует, либо предыдущим элементом. Получается, что перечисление может состоять в общем случае из элементов различных типов!
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
16.05.2017, 00:40
Цитата Сообщение от codesurfer Посмотреть сообщение
Подскажите, а при каких вообще условиях размер enum может перестать быть равен 4 байта?
C++
1
2
3
4
5
// underlying_type является int
// размер которого не фиксирован
// и может быть разным
// в зависимости от платформы
enum sample { ololo };
1
0 / 0 / 0
Регистрация: 09.02.2017
Сообщений: 69
16.05.2017, 11:51  [ТС]
Всем добрый день.

Спасибо за Ваши ответы. По вашим наводкам я покопался в разных источниках где и нашел ответы на все свои вопросы.
Тема перечислений оказалась не такой простой как может показаться. Поэтому ниже привожу ссылки на русскоязычные источники которые в достаточной степени освещают тему перечислений, того как это было изначально в ANSI C89 и того как это есть сейчас начиная с C++11.

1. Язык программирования C (Брайан У. Керниган, Деннис М. Ритчи), стр. 320, Приложение А.8.4.
2. Эффективный и современный С++. 42 рекомендации по использованию C++11 и C++14 (Скотт Мейерс), стр. 84, глава 3.4.

Всем удачи и ещё раз спасибо.
0
284 / 232 / 114
Регистрация: 07.09.2016
Сообщений: 584
16.05.2017, 12:47
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
 
const unsigned long long x = ~0ull;
enum A : unsigned long long {
    A1,
    A2,
    A3 = x
};
 
using namespace std;
int main() {
    cout << typeid(underlying_type<A>::type).name() << endl;
    cout << x << " " << static_cast<unsigned long long>(A::A3) << " " << A::A3 << endl;
}
Вот это вот похоже на баг студийного компилятора и вообще засада какая-то. MS VS 15 тоже лажу выдает.
А вот тут например все одинаковое: http://cpp.sh/2exj
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
16.05.2017, 12:47
Помогаю со студенческими работами здесь

Передача элементов перечисления (enum) в конструктор
Всем добрый день! Заметил некоторые странности при передачи элементов перечисления в конструктор. Вот пример: #include...

Перечисления enum. Хранение типа телефонного номера
Ввести в массив структур N записей из телефонной книжки (фамилия, имя, номер телефона, тип номер (домашний, рабочий, мобильный)). Вывести...

Перечисления фиксированного типа ( enum-base ). Ошибка при компиляции
Если я правильно понимаю, следующий enum ( далее — енум ): enum : &lt; type &gt; { &lt; CONST_NAME &gt; }; , где &lt; type &gt; — некий скалярный...

Перечисления (enum): для чего они нужны? Как, когда и какими перечислениями уместнее пользоваться?
Предположим есть такой код: #include &lt;iostream&gt; #include &lt;iomanip&gt; #include &lt;Windows.h&gt; enum airplanes {SU6, SU29, SU34}; //...

Enum == int !=enum?
enum Flags{ Flag1 = 1, Flag2 = 2}; int main() { Flags a = Flag1, b = Flag2; a = a | b; } error C2440: =: невозможно...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru