Home > Mobile >  Default initialization of class's members depend on each other, undefined behaviour?
Default initialization of class's members depend on each other, undefined behaviour?

Time:01-05

In other words, is this undefined behaviour?

class Foo {
public:
    int a = b; 
    int b = a; 
};

I thought it is undefined behaviour since when you initialize a, you use the value of b, which is undefined.

But this program, compiled using x86-64 GCC 12.2, using -std=c 20 -Wall -Wextra -Wpedantic -Werror gives no error and returns the expected output:

#include <iostream>

class Foo {
public:
    int a = b; 
    int b = a; 
};

int main() 
{
    Foo bar{.a = 42}; 
    std::cout << bar.a << ' ' << bar.b;
}

Godbolt link.

So is this well-defined behaviour, or is it undefined behaviour and the compiler is missing the issue?

CodePudding user response:

Foo bar{.a = 42}; is initializing a with 42. The default member initializer = b in the class definition is ignored if you give an initializer for the member explicitly.

So the shown program has well-defined behavior and will output 42 42.

If you hadn't specified an explicit initializer for a, then the program would have undefined behavior for the reason you gave: It reads b outside its lifetime (or with indeterminate value). (This happens already in the initialization, not only when reading a or b later in the output statement.)

However, undefined behavior does not mean that the program must behave differently or that the compiler must notify you about it. Undefined behavior means no guarantees, so 42 42 would be a valid output as well, but so would be any other or none at all.

CodePudding user response:

So is this well-defined behaviour, or is it undefined behaviour and the compiler is missing the issue?

This is well-defined behavior. By writing Foo bar{.a = 42};, you're explicitly initializing the data member a with 42. This means that the default member initializer for a will be ignored. In other words, the default member initializer b will not be used to initialize a and so the program doesn't actually use an indeterminate value.

  • Related