联合黑客进行端序测试和字节交换

对于联合,写入一个成员并从其他成员读取(char数组除外)是UB。

//snippet 1(testing for endianess): union { int i; char c[sizeof(int)]; } x; xi = 1; // writing to i if(xc[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; xi = 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 xi; // reading from xi } 

Snippet 1是合法的C或C ++但不是代码片段2.我是否正确? 有人可以指向标准部分,它表示可以写入union的成员并从另一个成员读取char数组。

我相信它(片段1)在技术上是不允许的,但大多数编译器仍允许它,因为人们使用这种代码。 GCC甚至certificate它受到支持。

在sizeof(int)== 1的某些机器上遇到问题,也可能在某些既不是大端也不是小端的机器上都有问题。

使用可用的function将单词更改为正确的顺序,或使用配置宏设置此function。 无论如何,您可能需要识别编译器和操作系统。

有一种非常简单的方法可以解决未定义的行为(很多未完成的behvaiour,几乎在每个编译器中定义;))。

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

这有额外的好处,几乎每个编译器都会看到你正在memcpying一个恒定的字节数并完全优化memcpy,导致与你的代码片1完全相同的代码,同时完全符合规则!