我有以下 struct :

typedef struct __attribute__ ((__packed__))
{
    uint16_t a;
    uint32_t b;
} st_t;

-&燃气轮机;"b"成员未对齐.

当我执行以下操作时,gcc会发出警告:

st_t st;
uint32_t * b_p = &st.b;
*b_p = 0;

警告日志(log):

taking address of packed member of 'struct <anonymous>' may result in an unaligned pointer value

但当我执行以下操作时,它不会发出任何警告:

st_t st;
st_t * st_p = &st;
st_p->b = 0;

我不明白为什么在第二种情况下它没有发出警告,因为我仍然在访问一个未对齐的成员.

推荐答案

无法提供标准报价,因此其他人肯定会写出更好的答案,但这里有一个简短的答案.

对于压缩 struct ,从"压缩 struct "的定义来看,编译器必须为任何成员访问生成工作机器代码.未对齐的访问是已知的,将为CPU进行适当的处理.

然而,假设指向int的指针指向一个有效的int,这可能意味着它是对齐的(或者会出现"总线错误"或类似情况).编译器 for each int指针解引用生成有效的未对齐访问机器代码在CPU上效率很低,所以编译器基本上是has to做出这个假设的.

所以,若编译器注意到一个指向未对齐地址的指针,它会发出正确的警告,因为这在某些CPU上是非法操作,即使是合法的,也可能比对齐访问慢.它不会对压缩 struct 发出警告,因为程序员会爆发性地说"这是未对齐的,请通过压缩 struct 来处理".

C++相关问答推荐

定义_MISIX_C_SAL时,在MacOS上编译失败,并出现奇怪错误

有什么方法可以检测SunOS上的SparcWorks吗?

C/SDL程序,渲染不使用我的渲染器

有没有更简单的方法从用户那里获取数据类型来计算结果

如何将长字符串转换为较小的缩写,该缩写由第一个字符、最后一个字符和中间的字符数组成?

如何在ASM中访问C struct 成员

S的这种管道实施有什么问题吗?

用C++实现余弦函数

从C文件中删除注释

为 struct 中的数组动态分配内存时出错

OSDev--双缓冲重启系统

表达式x&;&;(~x)应该返回1还是0?它依赖于编译器吗?

STM32 FATFS用户手册(Um1721)中的代码正确吗?

基于蝶数恰好有8个除数的事实的代码

I';我试着从.txt文件中读取文本,并用c计算其中的单词数量

令人困惑的返回和 scanf 问题相关

根据输入/输出将 C 编译过程分为预处理、编译、汇编和链接步骤

SSE 向量与 Epsilon 的比较

快速准确计算double的小数指数

C23 中的 [[reproducible]] 和 [[unsequenced]] 属性是什么?什么时候应该使用它们?