【发布时间】:2023-04-02 03:58:01
【问题描述】:
程序在 C 中使用 std=c99,这是在 64 位机器上。
struct epochs {
volatile unsigned int epoch : 1;
volatile unsigned int pulse : 1;
volatile unsigned int active0 : 7;
volatile unsigned int active1 : 7;
volatile unsigned int counter0 : 24;
volatile unsigned int counter1 : 24;
};
当我检查 sizeof(epochs) 时,它给了我 12。
我可以告诉 gcc 不要通过添加 __attribute((packed)); 来填充它。所以我可以解决它。但是我真的很想知道为什么要添加 4 个字节来填充这个 64 位结构?
这里主要是这个结构需要 64 位,因为它在 64 位原子交换操作中一次全部更新,这当然不适用于 12 字节值。
【问题讨论】:
-
通常允许对位域进行填充以提高性能,我最好的猜测是编译器在您的数据成员之间添加了填充,以确保它们在字节边界上对齐。添加打包属性确实会告诉编译器不要添加填充以提高性能。
-
如果您想要可移植/可重现的行为,请不要使用位域。
-
struct epochs { unsigned int counter0 : 24, pulse : 1, active0 : 7, counter1 : 24, epoch : 1, active1 : 7; };在我的 linux、solaris 和 aix 上是 8 个字节。 (顺便说一句,为什么都是volatile?) -
@Exodist
volatile不提供这些语义(但原子操作提供) -
@Exodist 有 atomic loads in gcc,它们在很大程度上遵循 C11/C++11 模型。
标签: c struct padding atomic compare-and-swap