std::construct_at 在现有对象之上跳过某些字段的重新初始化

std::construct_at on top of existing object skipping re-initialization of some fields

在下面的程序中,在常量表达式中,创建了一个 A 的临时对象,并初始化了所有字段,然后函数 f 创建了另一个 A 的对象相同的地址,跳过(重新)初始化字段 x,之后读取:

#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 接受得很好。但是其他编译器抱怨,例如铿锵声:

note: read of uninitialized object is not allowed in a constant expression
    return a.x; 
           ^

演示:https://gcc.godbolt.org/z/87zrEb7q7

确实xstd::construct_at<A>(&a)中没有初始化,但是在A{5}中初始化了。

这里是哪个编译器?

我确信这是 UB,而 GCC 是错误的。

std::construct_at<A>(&a) 创建一个新的 A 对象,因此其中有一个新的 int x 成员。该新对象未初始化。

为了合法,必须有一个特殊的规则,即未初始化的对象可以根据它们占用的内存内容获取值,但我认为不存在这样的规则。 [basic.indet]没提