C++中含原生T与包装T的union成员访问是否有合规保证?
关于C++中裸类型与包装类型Union的合规性问题
咱们直接拆解你提出的两个问题,结合示例代码和C++标准规定来分析:
问题1:包含包装类型与该类型本身的union是否存在合规性保证?
答案是没有合规性保证。
你给出的示例里,union Example包含了裸类型T(比如int)和一个包装它的结构体Wrapped。C++11及后续版本中,union的安全访问核心规则是公共初始序列(common initial sequence),但这个规则仅适用于结构体/联合体之间的情况——你的裸类型value并不是结构体,完全不适用该规则。
更关键的是:C++标准并没有强制要求包装结构体Wrapped和裸类型T的内存布局兼容。虽然多数编译器会让Wrapped的内存布局和T完全一致(毕竟结构体里只有一个成员),但这只是编译器的非标准扩展行为,不属于标准强制要求,不能用来编写可移植代码。
问题2:能否将T与包装后的T放入union中并随意访问检查它们?
答案同样是不能。
看你的示例代码:
union Example { int value; struct Wrapped { int wrapped; } wrapper; }; Example ex; ex.value = 12; cout << ex.wrapper.wrapped; // 这是未定义行为
当你给ex.value赋值后,value就成为了union的活动成员。此时访问非活动成员wrapper.wrapped,完全不符合C++标准的合法访问条件——因为公共初始序列规则不适用(裸类型不是结构体),所以这属于未定义行为。
编译器对这段代码的处理是不可预料的:可能输出12,可能输出垃圾值,甚至可能直接崩溃,一切都没有标准层面的保障。
内容的提问来源于stack exchange,提问作者Zeta
相关产品推荐
相关产品推荐

