In the next program struct B
has immediate consteval
default constructor, which does not initialize i
field. Then this constructor is used to make a temporary and its i
field remains untouched:
struct B {
bool b = true;
int i;
consteval B() {}
};
static_assert( B{}.b );
Clang and MSVC are fine with it. But GCC complains:
error: 'B{true}' is not a constant expression
7 | static_assert( B{}.b );
| ^
error: 'B()' is not a constant expression because it refers to an incompletely initialized variable
Demo: https://gcc.godbolt.org/z/x4n6ezrhT
Which compiler is right here?
CodePudding user response:
From cppreference's consteval specifier (since C 20):
The consteval specifier declares a function or function template to be an immediate function,
...
An immediate function is a constexpr function, and must satisfy the requirements applicable to constexpr functions or constexpr constructors, as the case may be.
And if we go to cppreference's constexpr specifier (since C 11):
A constexpr function must satisfy the following requirements:
...
A constexpr constructor whose function body is not =delete; must satisfy the following additional requirements:
...
for the constructor of a class or struct, every base class sub-object and every non-variant non-static data member must be initialized.
However, as @user17732522 accurately pointed out in a comment below, this last requirement applies only until C 20.
So I would say i
doesn't need to be initialized in this case (Clang/MSVC are correct, gcc is wrong).