对于 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/