将指向部分构造的对象的指针转换为指向基 class 的指针是否合法?

Is it legal to cast a pointer to a partially constructed object to a pointer to a base class?

也就是说,这样的事情总是合法的吗?

struct Derived;
struct Base { Base(Derived*); };
struct Derived : Base { Derived() : Base(this) { } };
Base::Base(Derived *self) {
    if(static_cast<Base*>(self) != this) std::terminate();
}

int main() {
    Derived d; // is this well-defined to never call terminate?
}

在计算 static_cast 时,self 尚未指向 Derived 对象——该对象正在构建中。例如。如果 Derived 有数据成员,它们的构造函数就不会被调用。转换是否仍然保证定义为行为,导致指针等同于 Basethis(确实指向完全构造的 Base 基础 class 子对象)?

我认为接近回答这个问题的标准引述是 [conv.ptr]/3

...The result of the conversion is a pointer to the base class subobject of the derived class object. ...

但我认为 还没有派生 class 对象,所以会发生什么?如果确实未定义,self != static_cast<Derived*>(this) 的答案会改变吗?

(Clang 和 GCC 编译并且 运行 这“符合预期”。)

这很好:[class.cdtor]/3

To explicitly or implicitly convert a pointer (a glvalue) referring to an object of class X to a pointer (reference) to a direct or indirect base class B of X, the construction of X and the construction of all of its direct or indirect bases that directly or indirectly derive from B shall have started and the destruction of these classes shall not have completed, otherwise the conversion results in undefined behavior. ...

它要求源类型(以及从目标类型继承的任何其他基类)开始它的构造函数并且没有完成它的析构函数。即使是基类的初始值设定项也算作派生构造函数的开始;该标准包含一个非常相似的示例。