如果我在8位处理器的代码中执行以下操作:
typedef union
{
unsigned long longn ;
unsigned char chars[4];
} longbytes;
longbytes.chars[0]
总是会成为longbytes.longn
的最低字节,还是依赖于字节序/编译器/平台/目标/运气等?我已经查看了我的编译代码的反汇编,这就是我在特定情况下的情况,但我很好奇这段代码是否可移植。
答案 0 :(得分:7)
有几个原因导致无法携带:
chars[0]
寻址最低字节unsigned long
不能保证与4
字符一样长,因此根据平台,您甚至可能无法获得完整的long
(或sizeof(long
} )可能比4
更小,你可以进一步阅读,但至少对8Bit处理器不太可能。总而言之,这些代码根本不可移植。
答案 1 :(得分:4)
一般情况下,如果你需要关心字节序,那么你做错了什么,需要解决你的问题(例如使用移位和掩码,或序列化/反序列化)。
例如,你可以做类似的事情而不是联盟,而不是:
uint32_t pack(uint8_t byte0, uint8_t byte1, uint8_t byte2, uint8_t byte3) {
long result;
result = byte0;
result |= byte1 << 8;
result |= byte2 << 16;
result |= byte3 << 24;
return result;
}
uint8_t unpack(int byteNumber, uint32_t value) {
return (value >> (byteNumber * 8));
}
答案 2 :(得分:1)
这取决于平台如何在内部存储long
。写入联合的一个元素然后从另一个元素中读取是不可移植的。
答案 3 :(得分:1)
union
数据结构是可移植的,只要您不通过写入其中一部分并从另一部分读取而导致未定义的行为。具体而言,写入unsigned long
并从unsigned char[4]
读取或反之亦然是未定义的行为。