In the following program, in a constant expression, a temporary object of A is created with all fields initialized, and then function f creates another object of A at the same address, skipping (re)initialization of the field x, which is read afterwards:
#include <memory>
struct A {
int x;
constexpr A() {}
constexpr A(int xx) : x(xx) {}
};
constexpr int f(A && a) {
std::construct_at<A>(&a);
return a.x;
}
static_assert( f(A{5}) == 5 ); //ok in GCC only
GCC accepts it just fine. But other compilers complain, e.g. Clang:
note: read of uninitialized object is not allowed in a constant expression
return a.x;
^
Demo: https://gcc.godbolt.org/z/87zrEb7q7
Indeed x is not initialized in std::construct_at<A>(&a), but it was initialized in A{5}.
Which compiler is right here?