我有以下结构和" 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?
答案 0 :(得分:5)
问题是你有:
uint16_t x;
但是您尝试写入该内存位置,就好像它是unsigned
的位置一样。
如果您所在的系统中unsigned
和uint16_t
属于同一类型,则可以。但是在其他系统上,例如您用于代码示例的系统,您遇到了麻烦。
首先,这会导致undefined behaviour违反strict aliasing rule。 uint16_t
类型的变量只能通过uint16_t
类型的左值或字符类型写入。
但即使它没有违反严格的别名,你仍然可以通过在x
范围之外写字来引起UB。您可能正在将4或8个字节写入2字节的内存位置,因此它会溢出缓冲区。
如果x
的{{1}}不正确aligned,则可能还有UB。