C++ 字段并集与结构并集的区别

C++ 字段并集与结构并集的区别,c++,struct,union,bit-fields,C++,Struct,Union,Bit Fields,我正在定义一组结构来处理一些寄存器,当我定义结构时,我发现了定义简单字段的并集和结构的并集之间的区别。我不确定为什么会出现这种差异: #include <iostream> using namespace std; typedef union { uint16_t all_bits; struct { uint16_t a:4, b:4, c:4, d:3, e:1; }; } Example1_t; typedef

我正在定义一组结构来处理一些寄存器,当我定义结构时,我发现了定义简单字段的并集和结构的并集之间的区别。我不确定为什么会出现这种差异:

#include <iostream>

using namespace std;


typedef union
{

    uint16_t all_bits;
    struct
    {   
        uint16_t a:4, b:4, c:4, d:3, e:1;
    };  
}
Example1_t;

typedef union
{

    uint16_t all_bits;
    uint16_t a:4, b:4, c:4, d:3, e:1;

}
Example2_t;

    int 
main ()
{
    Example1_t example1;
    Example2_t example2;
    example1.all_bits = 0x8BCD;
    example2.all_bits = 0x8BCD;

    cout << "a " << std::hex << example1.a << " " << example2.a << std::endl;
    cout << "b " << std::hex << example1.b << " " << example2.b << std::endl;
    cout << "c " << std::hex << example1.c << " " << example2.c << std::endl;
    cout << "d " << std::hex << example1.d << " " << example2.d << std::endl;
    cout << "e " << std::hex << example1.e << " " << example2.e << std::endl;

    return 0;
}
输出:

d b、c、d c、b、d d 0 5
e1

学究式的回答是:

您的代码具有未定义的行为。向联合字段写入和从另一个字段读取都不能保证有效,因此,您看到的任何不一致都可以被手工处理为损坏的代码

事实上,如此多的人在野外依赖于这种破坏行为的一致性,以至于所有现代编译器仍然在这里提供可预测的功能,而忽略了一些优化机会。因此,在您的代码中确实存在一些特定的东西,使其按其方式运行:

在示例1中,并集有两个重叠字段:所有位和结构。在该结构中,每个成员都有不同的存储


<2>中,a、b、c、d和e都是并集的独立字段,所以它们都有重叠存储。

作为FYI:使用像类型的联合这样的UB是C++中的,即使这是常见的实践。如果打开优化,编译器将对其进行优化。。。。但它也将正确跟踪数据依赖关系。有了union,编译器有权根据严格的别名规则声明不存在任何数据依赖项。另外还有一个用于添加关于UB的注释。这确实有助于答案在技术上和功能上都是正确的。