Fed*_*dor 5 c++ language-lawyer constexpr
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
Run Code Online (Sandbox Code Playgroud)
GCC 接受得很好。但其他编译器会抱怨,例如 Clang:
note: read of uninitialized object is not allowed in a constant expression
return a.x;
^
Run Code Online (Sandbox Code Playgroud)
演示: https: //gcc.godbolt.org/z/87zrEb7q7
确实x没有在 中初始化std::construct_at<A>(&a),但它是在 中初始化的A{5}。
这里是哪个编译器?
我确信这是 UB,而 GCC 是错误的。
std::construct_at<A>(&a)创建一个新A对象,从而int x在其中创建一个新成员。该新对象未初始化。
为了使其合法,必须有一个特殊的规则,即未初始化的对象可以根据它们占用的内存内容获取值,但我认为这样的规则不存在。[basic.indet] 没有提到它。