在不同的体系结构上转换指针类型

MC9*_*C93 6 c pointers casting endianness

我有以下结构和"getter"函数,它返回a强制转换为无符号整数:

struct s {
    uint32_t a;
};

void get_a(struct s *st, unsigned *ret)
{
    *ret = (unsigned)st->a;
}
Run Code Online (Sandbox Code Playgroud)

运行以下代码:

struct s st;
uint16_t x;

st.a = 1;
get_a(&st, (unsigned *)&x);
Run Code Online (Sandbox Code Playgroud)

对于x86_64,i686,armv7hl,ppc64le等架构x == 1,但对于ppc64 x == 0.为什么是这样?Little-vs. big-endian?

M.M*_*M.M 5

问题是你有:

uint16_t x;
Run Code Online (Sandbox Code Playgroud)

但是你会尝试写入该内存位置,就像它的位置一样unsigned.

如果你的系统上,其中unsigned和uint16_t是同一类型,这是好的.但是在其他系统上,例如您用于代码示例的系统,您遇到了麻烦.

首先,这会通过违反严格别名规则导致未定义的行为.类型的变量只能通过类型的左值或字符类型写入.uint16_tuint16_t

但即使它没有违反严格的别名,你仍然可以通过写出超出界限来引起UB x.您可能正在将4或8个字节写入2字节的内存位置,因此它会溢出缓冲区.

如果x没有正确对齐,也可能有UB unsigned.