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开始计数)).在这种情况下,如果我们切换5到4源代码,将会出现完全相同的输出.使用gcc 4.6.3编译,就像在Godbolt编译器资源管理器上一样.
两台机器都是小端.
为什么会这样?
假设类型uint16_t的对齐要求是2,那么您的代码具有未定义的行为1,因为此指针:(uint16_t *)&packet_data[5]未正确对齐.
如果使用对齐的偏移量(如4),则结果应与定义的行为相同.
1(引用自:ISO/IEC 9899:201x 6.3.2.3指针7):
指向对象类型的指针可以转换为指向不同对象类型的指针.如果生成的指针未针对引用的类型正确对齐,则行为未定义.