c++ - Union hack 用于字节序测试和字节交换

标签 c++ c unions

对于 union 体,写入一个成员并读取另一成员(字符数组除外)是UB。

//snippet 1(testing for endianess): 

union
{
    int  i;
    char c[sizeof(int)];
} x;

x.i = 1;                     // writing to i
if(x.c[0] == 1)              // reading from c[0]
{   printf("little-endian\n");
}
else
{   printf("big-endian\n");
}

//snippet 2(swap bytes using union):

int swapbytes()
{
    union                   // assuming 32bit, sizeof(int)==4
    {        
        int  i;
        char c[sizeof(int)];
    } x;
    x.i = 0x12345678;       // writing to member i
    SWAP(x.ch[0],x.ch[3]);  // writing to char array elements
    SWAP(x.ch[1],x.ch[2]);  // writing to char array elements
    return x.i;             // reading from x.i 
}   

代码段 1 是合法的 C 或 C++,但代码段 2 不是。我对吗?有人可以指出标准的一部分,其中规定可以写入 union 体成员并从另一个字符数组成员读取。

最佳答案

有一种非常简单的方法可以绕过未定义的行为(几乎每个编译器中都定义了未定义的行为;))。

uint32_t i = 0x12345678;
char ch[4];
memcpy( ch, &i, 4 );

bool bLittleEndian = ch[0] == 0x78;

这还有一个额外的好处,几乎每个编译器都会看到您正在 memcpy 恒定数量的字节,并完全优化 memcpy ,从而产生与代码片段 1 完全相同的代码,同时完全符合规则!

关于c++ - Union hack 用于字节序测试和字节交换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6359629/

相关文章:

c++ - MSVC2015 : inconsistencies with permissions 上的实验性 C++17 文件系统

c++ - 将 std::normal_distribution 绑定(bind)到 std::function 以存储在 std::vector 中

c - 如何根据它们的差异是否最接近给定数字来选择两个数字?

c++ - 开发人员无法执行 .exe 错误 193 : %1 not a valid win32 application

c++ - union 与位掩码和位移位

c++ - 我怎样才能防止无名的结构\union ?

java - 使用单个循环从数组中获取所有子数组

c - 在 malloc 之后直接为 char 指针赋值会导致段错误

c++ - 在 C/C++ 中释放/删除 union malloc/new Array

c++ - 如何让部分模板与子类一起使用