为什么GCC垫此位字段? [英] Why does GCC pad this bit-field?
问题描述
计划是在C使用std = C99,这是一个64位的机器上。
结构时代{
挥发性unsigned int类型划时代:1;
挥发性unsigned int类型脉冲:1;
挥发性unsigned int类型ACTIVE0:7;
挥发性unsigned int类型正在进行1:7;
挥发性unsigned int类型计数器0:24;
挥发性unsigned int类型计数器1:24;
};
当我检查的sizeof(时代),它给了我12。
我可以通过添加__attribute告诉GCC不填充它((包装));这样我就可以解决它。不过,我真的很想知道为什么4个字节被添加到该垫64位的结构?
这里最主要的是,这个结构需要,因为它是在64位原子交换操作全部更新一次,当然也不会在12字节的值工作,是64位。
挥发性unsigned int类型划时代:1;
挥发性unsigned int类型脉冲:1;
挥发性unsigned int类型ACTIVE0:7;
挥发性unsigned int类型正在进行1:7;
^ 32位(4字节)
挥发性unsigned int类型计数器0:24;
^ 32位(4字节)
挥发性unsigned int类型计数器1:24;
^ 32位(4字节)
所以4个字节以上。
ç说:
(C99,6.7.2.1p10)如果有足够的空间,紧跟在结构的另一位字段位字段应装在同一单元的相邻位
块引用>有没有足够的空间把24位(
C0的
)更在32位单元(的可能大小unsigned int类型
在您的系统)已持有的16位(划时代
,脉冲
,ACTIVE0
,正在进行1
)。您可以使用
uin64_t
而不是使用unsigned int类型
来包在64位单元的位字段但它是实现定义您的系统是否支持这一点。
(C99,6.7.2.1p4)A位域应有类型_Bool是一个合格的或不合格的版本,符号整数,无符号整型,或其他一些实现自定义类型 。
块引用>Program is in C using std=c99, this is on a 64-bit machine.
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; };
when I check sizeof(epochs) it gives me 12.
I can tell gcc not to pad it by adding __attribute((packed)); so I can work around it. However I would really like to know why 4 bytes are added to pad this 64-bit structure?
The main thing here is that this structure NEEDS to be 64 bits because it is updated all at once in 64-bit atomic swap operations, which of course will not work on a 12-byte value.
解决方案volatile unsigned int epoch : 1; volatile unsigned int pulse : 1; volatile unsigned int active0 : 7; volatile unsigned int active1 : 7;
^ 32-bit (4 bytes)
volatile unsigned int counter0 : 24;
^ 32-bit (4 bytes)
volatile unsigned int counter1 : 24;
^ 32-bit (4 bytes)
So 4 bytes more.
C says :
(C99, 6.7.2.1p10) "If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit"
There is not enough space to put 24-bit (
counter0
) more in a 32-bit unit (likely the size ofunsigned int
in your system) that already holds 16-bit (epoch
,pulse
,active0
,active1
).You can use
uin64_t
instead of usingunsigned int
to pack your bit-fields in a 64-bit unit but it is implementation-defined whether your system supports it or not.(C99, 6.7.2.1p4) "A bit-field shall have a type that is a qualified or unqualified version of _Bool, signed int, unsigned int, or some other implementation-defined type."
这篇关于为什么GCC垫此位字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!