为什么指针算法在架构之间不一致?

Mat*_*toe 2 c x86 byte pointers arm

给出以下代码:

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");
Run Code Online (Sandbox Code Playgroud)

在我的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开始计数)).在这种情况下,如果我们切换54源代码,将会出现完全相同的输出.使用gcc 4.6.3编译,就像在Godbolt编译器资源管理器上一样.

两台机器都是小端.

为什么会这样?

250*_*501 5

假设类型uint16_t的对齐要求是2,那么您的代码具有未定义的行为1,因为此指针:(uint16_t *)&packet_data[5]未正确对齐.

如果使用对齐的偏移量(如4),则结果应与定义的行为相同.


1(引用自:ISO/IEC 9899:201x 6.3.2.3指针7):
指向对象类型的指针可以转换为指向不同对象类型的指针.如果生成的指针未针对引用的类型正确对齐,则行为未定义.