Объект enums установлен в значение, не равное любой из его соответствующих констант enums

Какое значение имеет объект enums, если он установлен в значение, не равное любой из его соответствующих констант enums?

Рассмотрим следующий код:

enum foobar{ FOO = 1, BAR = 5 }; enum foobar baz = 5; enum foobar qux = 42; 

Переменная baz устанавливается на целочисленное значение 5 , а переменная qux устанавливается на целочисленное значение 42 .

Я подозреваю, что переменная baz будет содержать значение BAR , но я не уверен в переменной qux . Никакой константе enums не было присвоено значение 42 , так что происходит, когда переменная enum foobar установлена ​​на такое значение?

Является ли стандарт C99 явным о результатах?

Стандарт проекта C99 , судя по всему, не ограничивает перечислитель исключительно на значения его членов, но он говорит, что нулевой тип перечислений должен быть способен представлять значения всех его членов. Это описано в разделе 6.7.2.2 enums :

Каждый перечисленный тип должен быть совместим с символом char, целочисленным типом со знаком или беззнаковым целым типом. Выбор типа определяется реализацией, 110), но должен быть способен представлять значения всех членов enums.

и поэтому вы будете полагаться на поведение, определенное реализацией, если вы используете значение, большее, чем члены определяют. В случае со знаком целочисленного переполнения приводит к неопределенному поведению в соответствии с разделом 5 который гласит:

Если при оценке выражения возникает исключительное условие (т. Е. Если результат не определен математически или нет в диапазоне представляемых значений для его типа), поведение не определено.

Обычно мы видим, что enumsм присваиваются значения за пределами тех, которые указаны их членами, когда они используются для представления полей бит.

Переменная qux не будет содержать ни одного из значений enum s. Его значение будет равно 42 в базовом типе, который компилятор выбирает для представления foobar , который определяется реализацией. Это не представляет проблемы, когда значение равно 42 , но это может стать проблемой, когда константа не соответствует типу, выбранному компилятором для вашего enums.

Одной из причин, почему компилятор позволяет присваивать значения, отличные от констант enum является поддержка перечислений «флаг», когда ожидается, что константы будут объединены в побитовые операции:

 enum foobar { foo = 1 , bar = 2 , baz = 4 } test = (foo | baz); 

Переменная test выше содержит значение 5 , которое не соответствует какой-либо из констант enum .

 enum foobar{ FOO = 1, BAR = 5 }; enum foobar baz = 5; 

заявление baz эквивалентно:

 enum foobar baz = BAR; 

поскольку BAR является значением int 5 .

Это заявление также справедливо:

 enum foobar qux = 42; 

C говорит, что тип enum представляет собой целочисленный тип, достаточно большой для представления всех его констант enums. Если тип enum недостаточно велик, значение преобразуется в целочисленный тип enums как для каждого целочисленного типа в соответствии с правилами целочисленного преобразования (c99, 6.3.1.3). Это целочисленное преобразование может быть определено реализацией (см. 6.3.1.3p3).