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

C++14中访问union的非活跃成员是否合法?

C++14中访问union非活跃成员的合法性问题

我查阅了大量资料后,对C14里访问union的非活跃成员是否合法感到困惑。我知道在C11及更早版本中,这属于未定义行为。

请问是否允许像以下代码这样使用union?

typedef union _BYTE_VAL_T
{
    unsigned char Val;
    struct
    {
        unsigned char b0:1;
        unsigned char b1:1;
        unsigned char b2:1;
        unsigned char b3:1;
        unsigned char b4:1;
        unsigned char b5:1;
        unsigned char b6:1;
        unsigned char b7:1;
    } bits;
} BYTE_BITS_T;


int main()
{
   BYTE_BITS_T reg;
   reg.bits.b5 = 0x1;
   std::cout << reg.Val; // use of inactive member
}

解答

  1. C++14标准层面的规则
    C14确实新增了“union的所有非静态数据成员地址相同”的规定,但这一规则并未直接授权访问非活跃成员。从标准的严格定义来看,C14中访问union的非活跃成员仍然属于未定义行为——直到C++17才补充了更宽松的规则:若union的两个成员为标准布局类型,且它们的共同初始子序列覆盖整个成员,则允许通过一个成员赋值后访问另一个成员的对应部分。

  2. 代码中的具体问题

  • 代码里的位域结构体属于实现定义行为:位域的排列顺序(比如b0对应字节的最低位还是最高位)、填充方式都由编译器决定,跨平台可能出现不一致的结果。
  • 虽然主流编译器(GCC、Clang、MSVC)大多支持这种“类型双关”的union用法,将其作为编译器扩展,但这并非C++14标准所保证的合法行为。
  1. 总结
    从标准规范角度,C++14中你的代码写法不合法;但从实际工程角度,多数编译器会支持该写法,不过需要承担位域布局带来的跨平台风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 18:54:55