Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enum Class Default Initialization

Tags:

c++

c++11

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?

like image 314
tangy Avatar asked Dec 22 '18 17:12

tangy


2 Answers

[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) to T


[basic.types]/9 ... enumeration types ... are collectively called scalar types.

Put together, ALPHA() is equivalent to static_cast<ALPHA>(0)

like image 76
Igor Tandetnik Avatar answered Sep 22 '22 08:09

Igor Tandetnik


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) to T

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.

like image 36
Jans Avatar answered Sep 21 '22 08:09

Jans