Reputation: 9619
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
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
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