给定以下代码:
unsigned char *packet_data = (unsigned char *)malloc(7);
memset(packet_data, 0, 7);
uint16_t crc = 0xa8a9;
*((uint16_t *)&packet_data[5]) = (crc >> 8) | (crc << 8);
for (int i = 0; i < 7; i++) {
printf("%02X ", packet_data[i]);
}
printf("\n");
在我的 Mac (x86_64) 上,输出如预期的那样是 00 00 00 00 00 A8 A9(A8 进入字节 5(从 0 开始计数))。用 clang 编译 (LLVM 7.3.0)
然而,在 armv5tejl 机器上,输出是 00 00 00 00 A8 A9 00(A8 进入字节 4(从 0 开始计数))。在这种情况下,如果我们在源代码上将 5
切换为 4
,则会出现完全相同的输出。使用 gcc 4.6.3 编译,like this on the Godbolt compiler explorer .
两台机器都是小端。
为什么会这样?
最佳答案
假设类型 uint16_t 的对齐要求是 2,那么你的代码有未定义的行为1,因为这个指针:(uint16_t *)&packet_data[5]
不是正确对齐。
如果您使用对齐的偏移量,如 4,结果应该与定义的行为相同。
1(引自:ISO/IEC 9899:201x 6.3.2.3 Pointers 7):
指向对象类型的指针可以转换为指向不同对象类型的指针。如果
结果指针未针对引用类型正确对齐,行为是
未定义。
关于c - 为什么指针算法在架构之间不一致?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40011516/