为什么GCC垫此位字段? [英] Why does GCC pad this bit-field?

查看:116
本文介绍了为什么GCC垫此位字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

计划是在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 of unsigned int in your system) that already holds 16-bit (epoch, pulse, active0, active1).

You can use uin64_t instead of using unsigned 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆