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

C++读取联合体同类型非活跃成员是否为UB?兼谈C标准差异

读取联合体非活跃成员是否属于C++未定义行为?

先看这段C++代码:

union A{
  int a;
  int b;
};
int main(){
  A u = {.a = 0};
  int r = u.b; // #1 这是未定义行为吗?
}

C++标准下的判定

根据C++标准[class.union]条款:

在联合体中,非静态数据成员若其名称指代的对象生命周期已开始且未结束,则该成员是活跃的([basic.life])。联合体类型对象的非静态数据成员中,同一时间最多只能有一个处于活跃状态,也就是说,同一时间联合体中最多只能存储一个非静态数据成员的值。

本例中仅A::a为活跃成员,结合[basic.life]第7段的规定:

若出现以下情况,程序存在未定义行为:

  • 使用左值访问该对象,或

#1处代码尝试读取生命周期尚未开始的u.b,按照C++标准,该操作属于未定义行为。

对标准要求的讨论

从实际使用角度看,这个要求确实偏严格——毕竟a和b都是int类型,内存布局完全一致,读取u.b本质就是读取与u.a相同的内存内容,逻辑上不会产生歧义。但C++标准从对象生命周期的维度做了严格约束,核心是为了维护类型系统的一致性,避免在更复杂的类型场景下出现类型安全问题。

C标准的差异

C标准对该场景的要求更为宽松,其文档中有明确说明:

若用于读取联合体对象内容的成员,与最后用于向该对象存储值的成员不同,则会将值的对象表示的对应部分重新解释为新类型的对象表示(该过程有时被称为类型双关)。这可能会得到非值表示。

也就是说,C标准明确允许这种跨成员读取的操作,仅要求按对象表示重新解释类型即可,不存在未定义行为。而C与C的这一差异,并未在C标准差异文档中被明确指出。

内容的提问来源于stack exchange,提问作者xmh0511

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 19:00:15