You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++20下union布局兼容派生类为活跃成员时访问基类是否为定义行为

class B {
  void *ptr = nullptr;
 public:
  auto get() { return ptr; }
};
class D : public B {};

union U {
  B b;
  D d;
};

void *func() {
  U u{.d = D{}};
  return u.b.get(); // ???
}
行为判定结论

上述代码中标注???的行属于未定义行为,具体判定依据基于C++20标准如下:

  • 根据[class.union.general]章节规则:union的非静态数据成员生命周期开始且未结束时为活跃状态,同一时间union对象最多仅能有一个非静态数据成员处于活跃状态。代码中初始化的是u.d,因此d是当前唯一活跃成员,直接访问非活跃成员u.b本身违反标准要求。
  • 你提到的标准布局union公共初始序列例外规则,仅适用于直接读取两个成员公共初始序列的非静态数据成员,此处是调用成员函数,不属于该规则的适用范围,无法得到豁免。
  • 指针可互转换规则仅允许通过reinterpret_cast对满足互转换要求的对象指针做转换后访问,并没有放开union非活跃成员的直接访问限制。哪怕几个对象的地址完全重合,也不能绕过活跃成员规则直接调用非活跃成员的成员函数。
  • 目前主流GCC、Clang、MSVC编译器都对这类场景做了兼容扩展,实际运行通常会返回预期的nullptr,但这属于编译器的额外支持,不属于C++标准规定的合法行为。

内容的提问来源于stack exchange,提问作者Marcel Krüger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 18:27:05