C中未命名的零长度位字段是什么意思?

msc*_*msc 13 c structure bit-fields

我在C标准草案(n1570)中看到了以下示例:

$ 3.14第4段:宣布为以下结构:

struct 
{
        char a;
        int b:5, c:11, :0, d:8;
        struct 
        { 
            int ee:8; 
        } e;
}
Run Code Online (Sandbox Code Playgroud)

那么,什么:0意思呢?

我知道什么是字段,但:0没有名字,我不明白.

:0没有任何标识符的目的是什么?

Sam*_*nen 12

正如您之前链接的文档所解释的那样:

位字段和相邻的非位字段成员位于不同的存储器位置中.这同样适用于两个位字段,如果一个在嵌套结构声明中声明而另一个未声明,或者两者是由零长度位字段声明分隔,或者它们是由非位分隔-field成员声明

这是一种告诉编译器的方法,b并且c可以/将在同一个内存位置,但d必须与它们分开,并且可以同时修改为b/c


Sou*_*osh 7

首先,让我们看一下章节§6.7.2.1,结构和联合说明符,P11.它说,

实现可以分配足够大的任何可寻址存储单元来保持位域. 如果剩余足够的空间,则紧跟在结构中的另一个位字段之后的位字段将被打包到相同单元的相邻位中.[...]

但是,在这种情况下,我们明确地希望两个连续的位字段成员"可能"被打包到单个存储器位置以驻留在单独的存储器位置(即,可寻址存储单元),以上是强制它的方式.

下一段,P12,提及,

没有声明符但只有冒号和宽度的位字段声明表示 未命名的位字段.126)作为一种特殊情况,宽度为0的位域结构成员表示不再将其他位字段打包到放置了前一位字段(如果有的话)的单元中.

按照您的示例,这将确保围绕该:0位置的两个位字段成员将驻留在单独的内存位置(不在单个可寻址存储单元内,即使仍有足够的内存将它们打包成一个).这具有在两个位字段之间具有非位字段成员的类似效果,以强制分离存储器位置.

引用C11,第3.14章,NOTE 2(强调我的)

位字段和相邻的非位字段成员位于不同的存储器位置中.这同样适用于两个位字段,如果一个在嵌套结构声明中声明而另一个未声明,或者两者是由零长度位字段声明分隔,或者它们是由非位分隔-field成员声明.

另外,关于用法("为什么需要"部分)

[...]的位域bc不能同时修改,但ba,例如,可以是.


附录:

关于并发部分,请参见注1

两个执行线程可以更新和访问单独的内存位置,而不会相互干扰.

并且,从章节§5.1.2.4/ P1开始,

在托管实现下,程序可以同时运行多个执行线程(或线程).[...]

因此,根据标准,这是理论上可行的选择.