Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enumeration object set to a value not equal to any of its respective enumeration constants

What value does an enumeration object have if it is set to a value not equal to any of its respective enumeration constants?

Consider the following code:

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

enum foobar baz = 5;
enum foobar qux = 42;

The variable baz is set to the integer value 5, while the variable qux is set to the integer value 42.

I suspect the variable baz will hold the value BAR, but I'm unsure about the variable qux. No enumeration constant was assigned the value 42, so what happens when an enum foobar variable is set to such a value?

Is the C99 standard explicit about the outcome?

like image 452
Vilhelm Gray Avatar asked Jul 10 '14 17:07

Vilhelm Gray


2 Answers

Variable qux is not going to hold any of the enums values. Its value will be equal to 42 in the underlying type the compiler selects to represent foobar, which is implementation-defined. This would not present a problem when the value is 42, but it may become an issue when the constant does not fit in the type selected by the compiler for your enumeration.

One of the reasons why the compiler allows assignments of values other than enum constants is to support "flag" enumerations, when constants are expected to be combined in bitwise operations:

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

Variable test above holds the value of 5, which does not correspond to any of the enum constants.

like image 63
Sergey Kalinichenko Avatar answered Sep 18 '22 12:09

Sergey Kalinichenko


The C99 draft standard does not seem to restrict an enumerator to take on values of its members exclusively but it does say that the enumerators underlying type shall be capable of representing the values of all its members. This is covered in section 6.7.2.2 Enumeration specifiers:

Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined,110) but shall be capable of representing the values of all the members of the enumeration.

and so you will be relying on implementation defined behavior if you use a value greater then the members define. In the case of signed integer overflow leads to undefined behavior as per section 5 which says:

If an exceptional condition occurs during the evaluation of an expression (that is, if the result is not mathematically defined or not in the range of representable values for its type), the behavior is undefined.

Typically we see enums being assigned values outside of those specified by their members when they are used to represent bit fields.

like image 23
Shafik Yaghmour Avatar answered Sep 19 '22 12:09

Shafik Yaghmour