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

标签 c pointers x86 arm byte

给定以下代码:

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/

相关文章:

c - GCC 中用于除法的 SIMD (SSE) 指令

c - 通过 const 指针传递与通过内置类型的值传递。效率

x86 - 上证所指令 : Byte+Short

c++ - 如何在运行时简化代码生成?

pointers - Ifort : move_alloc() on attribute of a Pointer, intent(in) 触发错误

c - 如何制作可以运行 x86 十六进制代码的 C 程序

c - 字符串和管道中的奇怪行为

c - C 中的移位运算符(<<、>>)是算术运算符还是逻辑运算符?

java - Java 中的 C 数据类型

c - 将字符串指针传递给 C 中的函数时得到虚假结果