未命名的零长度位字段在C中的含义是什么?

时间:2017-08-28 10:27:21

标签: 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;
}

那么, :0是什么意思?

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

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

3 个答案:

答案 0 :(得分:12)

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

  

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

这是一种告诉编译器bc可以/将位于同一内存位置的方法,而d必须与它们分开,并且可以同时修改为{ {1}}

答案 1 :(得分:7)

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

  

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

但是,在这种情况下,我们明确地希望两个连续的位字段成员“可能”被打包到单个内存位置以驻留在单独的内存位置(即可寻址的存储单元),上面的方法是< em>强制它。

下一段,P12,提到,

  

没有声明符但只有冒号和宽度的位字段声明表示   未命名的位字段。 126)作为特殊情况,宽度为0的位字段结构成员表示不会将更多的位字段打包到其中的之前的位字段(如果有的话)被放置。

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

引用:0,章节§3.14,C11强调我的

  

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

另外,关于用法(“为什么需要”部分

  

[...]位字段NOTE 2b不能同时发生   已修改,但cb可以是。

附录:

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

  

两个执行线程可以更新和访问单独的内存位置而不会产生干扰   彼此。

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

  

在托管实现下,程序可以有多个执行线程   (或线程)并发运行。 [...]

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

答案 2 :(得分:3)

这是一种确保bit-fileds(否则可能会合并到单个内存位置)的方法。

例如,假设您有一个8位字符,但是您希望确保两个3位字段位于不同的位置(因此可以同时修改)。为此,您可以使用:

struct xyzzy {
    int first  : 3,
               : 0,
    int second : 3;
};

并且您不必担心手动填写空格,例如使用junk : 5

对于语言律师,C11 3.14 memory location /3州(我的重点):

  

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