调用具有通用基类的并集成员的虚拟函数作为另一个成员是未定义行为吗?

gvl*_*gvl 6 c++ unions type-punning

具体来说,我希望能够在嵌入式上下文中使用多态而不分配堆(因此无需动态分配)。在这里,我的担心似乎是,base尽管在成员中x或在成员中y处于“活动”状态时访问成员似乎是类型绑定的实例,即使它们共享相同的初始标头(和vtable结构)。下面的代码是否被视为定义的行为?

#include <iostream>
#include <new>

using namespace std;

struct Base {
    virtual const char *foo() { return "base"; }
};

struct X: public Base {
    const char *foo() override { return "d1"; }
};

struct Y: public Base {
    const char *foo() override { return "d2"; }
};

union DerivedAny {
    DerivedAny() {}
    Base& get() { return *launder(&b); }
    Base b = {};
    X x;
    Y y;
};

DerivedAny objs[3];

int main() {
    new (&objs[1].x) X;
    new (&objs[2].y) Y;
    cout << objs[0].get().foo() << endl;
    cout << objs[1].get().foo() << endl;
    cout << objs[2].get().foo() << endl;
}
Run Code Online (Sandbox Code Playgroud)

我已经使用GCC和Clang对其进行了编译,在两种情况下它们似乎都返回了预期的输出:

base
d1
d2
Run Code Online (Sandbox Code Playgroud)