我具有以下结构和“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
。为什么是这样?小端与大端? 最佳答案
问题是您有:
uint16_t x;
但随后您尝试写入该内存位置,就像它是
unsigned
的位置一样。如果您使用的是
unsigned
和uint16_t
是相同类型的系统,则可以。但是在其他系统上,例如在您用于代码示例的系统上,您遇到了麻烦。首先,这通过违反undefined behaviour导致strict aliasing rule。只能通过
uint16_t
类型或字符类型的左值写入uint16_t
类型的变量。但是,即使它没有违反严格的别名,您仍然会通过在
x
的边界之外编写来导致UB。您可能正在将4或8个字节写入2字节的内存位置,因此它将使缓冲区溢出。如果
x
对于unsigned
而言不是正确aligned,则也可能存在UB。关于在不同架构上强制转换指针类型,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31607620/