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

时间:2015-07-24 10:01:32

标签: c pointers casting endianness

我有以下结构和" getter"将a强制转换为无符号整数的函数:

struct s {
    uint32_t a;
};

void get_a(struct s *st, unsigned *ret)
{
    *ret = (unsigned)st->a;
}

运行以下代码:

struct s st;
uint16_t x;

st.a = 1;
get_a(&st, (unsigned *)&x);

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

1 个答案:

答案 0 :(得分:5)

问题是你有:

uint16_t x;

但是您尝试写入该内存位置,就好像它是unsigned的位置一样。

如果您所在的系统中unsigneduint16_t属于同一类型,则可以。但是在其他系统上,例如您用于代码示例的系统,您遇到了麻烦。

首先,这会导致undefined behaviour违反strict aliasing ruleuint16_t类型的变量只能通过uint16_t类型的左值或字符类型写入。

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

如果x的{​​{1}}不正确aligned,则可能还有UB。