может ли перечисление содержать целые числа без знака больше INT_MAX? - PullRequest
0 голосов
/ 08 декабря 2018
enum Some_Flag {
        SOME_FLAG_A = 0x00000000u,
        SOME_FLAG_B = 0x00000001u,
        SOME_FLAG_C = 0x00000002u,
        /* ... */
        SOME_FLAG_Z = 0x80000000u,
};

uint32_t a;
a = SOME_FLAG_Z;

Предполагая, что 32-битные целые числа ... Это действительно в C?

Стандарт мне кажется неоднозначным.

РЕДАКТИРОВАТЬ:

Цитирование стандарта:

6.4.4.3 Константы перечисления

Семантика

2 Идентификатор, объявленный как константа перечисления, имеет тип int.Прямые ссылки: спецификаторы перечисления (6.7.2.2).

6.7.2.2 Спецификаторы перечисления

Ограничения

2 Выражение, определяющее значение константы перечисления, должно быть целым числомконстантное выражение, значение которого представлено в виде целого числа.

Семантика

3 Идентификаторы в списке перечислителя объявляются как константы типа int и могут появляться везде, где это разрешено.127)перечислитель с = определяет свою константу перечисления как значение константного выражения.Если первый перечислитель имеет no =, значение его константы перечисления равно 0. Каждый последующий перечислитель с no = определяет свою константу перечисления как значение константного выражения, полученного путем добавления 1 к значению предыдущей константы перечисления.(Использование перечислителей с = может создавать константы перечисления со значениями, которые дублируют другие значения в том же перечислении.) Перечислители перечисления также известны как его члены.

4 Каждый перечисляемый тип должен быть совместим с char, целочисленный тип со знаком или целочисленный тип без знака.Выбор типа определяется реализацией, 128), но должен быть способен представлять значения всех членов перечисления.Перечислимый тип является неполным до тех пор, пока сразу после} не завершится список объявлений перечислителя и не завершится после него.

C11 черновик

Кажется, что ограничения явноуказывают, что перечисление является целым числом, но тогда 6.7.2.2_4, кажется, разрешает целые числа без знака ¿?

1 Ответ

0 голосов
/ 08 декабря 2018

Ваш код недействителен:

C90 (6.5.2.2, Спецификаторы перечисления):

Ограничения

Выражение, котороеопределяет значение константы перечисления должно быть выражением целочисленной константы, которое имеет значение, представляемое как int.

C99 (и без изменений в черновике C11) (6.7.2.2, Спецификаторы перечисления):

Ограничения

Выражение, которое определяет значение константы перечисления, должно быть выражением целочисленной константы, значение которого может быть представлено как int.

Ваши значения превышают диапазон 32-bit int, так что это ошибка (и требуется диагностика).

Обратите внимание, что это строго относится к "инициализаторам" констант перечисления.Например, если у нас есть

enum foo { BAR = 42u };

, то это ограничение говорит, что значение 42u должно быть в состоянии вписаться в int (что он делает; это просто без знака 42, а 42 помещается вint).

Сам тип BAR равен int (как ни удивительно, но не enum foo).

Но если вы объявите переменную типа enum foo,тогда его размер и подпись определяются реализацией.Он будет основан на некотором существующем целочисленном типе (который может хранить все значения перечисления), но какой тип фактически используется, может отличаться в разных реализациях (а также между различными enum типами).

...