CinCout
CinCout

Reputation: 9619

Order of initialization of class member variables

Consider the following code snippet:

class A
{
public:
    A(int a, int b) : j(a), i(j + b) {}
    int i, j;
};

int main()
{
    A a(10, 20);
    std::cout << a.i << " " << a.j << std::endl;
    return 0;
}

The standard says that the order of initialization of the member variables is the order in which they are declared. In this case, i will be initialized before j. Since j isn't initialized yet, i = *a garbage value* + 20, and then j is initialized with 10.

The code prints 20 10.

i.e., j was considered to be 0 when calculating i.

Does the standard guarantee to use default values for built-in types in such a scenario? Or is it just that the garbage value happened to be 0? Or is it undefined behavior?

Upvotes: 0

Views: 188

Answers (2)

walnut
walnut

Reputation: 22152

j + b is undefined behavior, because it uses an indeterminate value (that of j before its initialization) outside of one of the specific instances where doing so is allowed (all of which relate to char variants and std::byte, not int, indeterminate values).

In C++20 it will also have undefined behavior, because you are accessing j outside its lifetime. From what I can tell in C++17 and before the lifetime of j begins with allocation of its storage, because the initialization of j is vacuous. The definitions of vacuous initialization and lifetime change in C++20, though.

So in any case use of a variable before it is initialized is very ill-advised.

Upvotes: 1

eerorika
eerorika

Reputation: 238301

Does the standard guarantee to use default values for built-in types in such a scenario?

No. The value is indeterminate in this case.

Or is it undefined behavior?

Yes. The behaviour of reading an indeterminate value is undefined (except for narrow character types IIRC).

Upvotes: 1

Related Questions