Basically, given

enum class Color : int { R, G, B };
Color c;

is there any way for c to end up holding something other than R, G, B? Or, in other words, an underlying int other than 0, 1, or 2?

I know that the declaration of c above leaves it uninitialize, and that

Color c{};

would initialize it to R/0.

However, I've discovered that if the definition of the enumeration were

enum calss Color : int { R = 1, G, B };

then the {}-initialized c would have value 0, which does not correspond to any of R/G/B (I've verified that c == Color::enumerator returns false for any enumerator chosen from R, G, B; and static_cast<int>(c) is 0).

Now this, looks a bit edgy to me: if 0 does not underlay any of the enumerators, then why does {}-initialization give that value to the underlaying int?

2

There are 2 answers

0
Brian Bi On BEST ANSWER

Color is a scoped enumeration type, therefore its underlying type is fixed. (In your case you have explicitly specified it as int, but scoped enumerations also default to int when not explicitly specified. You can also explicitly specify an underlying type for unscoped enumerations.)

For an enumeration whose underlying type is fixed, all values of the underlying type are valid values for the enumeration. That is, Color can hold any int value. If it holds a value that none of its enumerators have, that just means that it won't compare equal to any of its enumerators. This may seem a bit strange, but the alternative would have been to give the program undefined behaviour, and most people would agree that we don't need any more undefined behaviour in C++.

(For an enumeration whose underlying type is not fixed, the rules are a bit more complicated. It is usually still possible to give them values that don't correspond to any enumerator, but the range of allowable values is narrower. Going outside that range results in undefined behaviour.)

0
NathanOliver On

c gets the value of zero because using {} value intialiazes c and for built in types (which is what underlies the enumeration) that is always zero initialization.

You can also manually assign a value that is not in the list of enumerations by using static_cast like

c = static_cast<Color>(42);