The*_*eer 6 c memory struct pointers alignment
我有以下结构:
typedef struct __attribute__ ((__packed__))
{
uint16_t a;
uint32_t b;
} st_t;
Run Code Online (Sandbox Code Playgroud)
->“b”成员未对齐。
当我执行以下操作时,gcc 会发出警告:
st_t st;
uint32_t * b_p = &st.b;
*b_p = 0;
Run Code Online (Sandbox Code Playgroud)
警告日志:
taking address of packed member of 'struct <anonymous>' may result in an unaligned pointer value
Run Code Online (Sandbox Code Playgroud)
但是当我执行以下操作时,它不会发出任何警告:
st_t st;
st_t * st_p = &st;
st_p->b = 0;
Run Code Online (Sandbox Code Playgroud)
我不明白为什么在第二种情况下它不会发出警告,因为我仍在访问未对齐的成员。
无法提供标准报价,因此其他人肯定会写出更好的答案,但这是一个简短的答案。
对于打包结构,从“打包结构”的定义来看,编译器必须为任何成员访问生成工作机器代码。未对齐的访问是已知的,并且将为 CPU 进行适当的处理。
然而,指向 int 的指针被假定指向一个有效的 int,这可能意味着它必须对齐(否则将出现“总线错误”或类似错误)。编译器为每个 int 指针取消引用生成有效的未对齐访问机器代码在重要的 CPU 上效率非常低,因此编译器基本上必须做出此假设。
因此,如果编译器注意到指向未对齐地址的指针,它会正确地发出警告,因为它在某些 CPU 上是非法操作,并且即使它是合法的,也可能比对齐访问慢。它不会对打包结构发出警告,因为程序员明确表示“这是未对齐的,请通过打包结构来处理它”。