Is the default initialization/construction of enum classes defined behavior?
Here is a minimal example(Try Online)
enum class ALPHA{
X = 0,
Y = 1,
Z = 2,
};
int main()
{
ALPHA a = ALPHA(); // use default constructor
ALPHA b{}; // use default initialization
std::cout <<static_cast<int>(a) << std::endl; // 0
std::cout <<static_cast<int>(b) << std::endl; // 0
return 0;
}
I get zero in both cases. So does the default initialization pick the first enum type(eg. here X = 0) always? I know that it is UB for standard enums but Im not sure about the semantics for enum classes? I looked this up on CPPReference too but didnt find any relevant information about it - Is it possible to get a standard reference too?
[expr.type.conv]/1 A simple-type-specifier (10.1.7.2) or typename-specifier (17.6) followed by a parenthesized optional *expression-list or by a braced-init-list (the initializer) constructs a value of the specified type given the initializer.
[expr.type.conv]/2 ... Otherwise, the expression is a prvalue of the specified type whose result object is direct-initialized (11.6) with the initializer.
[dcl.init]/(17.4) — If the initializer is
()
, the object is value-initialized.
[dcl.init]/8 To value-initialize an object of type
T
means:(8.4) — otherwise, the object is zero-initialized.
[dcl.init]/6 To zero-initialize an object or reference of type T means:
(6.1) — if
T
is a scalar type (6.9), the object is initialized to the value obtained by converting the integer literal 0 (zero) toT
[basic.types]/9 ... enumeration types ... are collectively called scalar types.
Put together, ALPHA()
is equivalent to static_cast<ALPHA>(0)
enumeration with fixed underlying type can be initialized by initializer-list if it's in the context of direct initialization and the initializer-list contains a single element with no narrowing conversion involved.
[dcl.enum]/8
[...] It is possible to define an enumeration that has values not defined by any of its enumerators.
[dcl.init]/6.1
To zero-initialize an object or reference of type T means:
(6.1) if
T
is a scalar type, the object is initialized to the value obtained by converting the integer literal 0 (zero) toT
That said, it's possible to have an enumeration initialized with values that is not in the range of its enumerators, but when it does fall in range, then it correspond to the enumerator.
In your example, the zero initialization initialize a
and b
to with 0
which correspond to the enumerator X
, meaning... your example is well defined.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With