c中零长度位字段的不同类型?

use*_*607 6 c bit-fields

Fount此语句零宽度位字段可以使下一个字段在下一个容器边界上对齐,其中容器的大小与位字段的基础类型相同

为了实现这一点,假设int是2个字节(16位),而short是1个字节(8位)以节省输入.另外,假设我们正在使用gcc编译器(很好地解释了与clang的差异).

struct foo {
    unsigned int a:5;
    unsigned int :0;
    unsigned int b:3;
}
Run Code Online (Sandbox Code Playgroud)

在内存中,这看起来像

struct address
   |            
   |
   v
   aaaaa000 00000000 bbb00000 00000000
Run Code Online (Sandbox Code Playgroud)

问题1:在我的理解它不会aaaaa000 00000000 0..00bbb00000...,所以bbb必须与容器对准直接按照当前的容器.这是真的吗?

继续,如果我指定

struct bar {
    unsigned short x:5; 
    unsigned int :0;
    unsigned short y:7;
}
Run Code Online (Sandbox Code Playgroud)

会这样吗?

struct address
   | short stops here         short starts  
   |      |                   |   
   v      v | this is uint  | v              
   xxxxx000 00000000 00000000 yyyyyyy0
Run Code Online (Sandbox Code Playgroud)

编辑1 有人指出短路不能少于16个字节.这与这个问题的观点略有不同.但是,如果对你很重要,你可以替换short使用char,并intshort

ams*_*ams 1

阅读上下文中的文本后更新:

您的示例的结果(更正为使用char):

struct bar {
    unsigned char x:5; 
    unsigned int :0;
    unsigned char y:7;
}
Run Code Online (Sandbox Code Playgroud)

看起来像这样(假设 16 位int):

 char pad pad      int boundary
  |    |   |        |
  v    v   v        v       
  xxxxx000 00000000 yyyyyyy0
Run Code Online (Sandbox Code Playgroud)

(我忽略了字节序)。

零长度位字段导致位置移动到下一个int边界。您定义int为 16 位,因此 16 减 5 得到 11 位填充。

它不会插入整个空白int。您链接的页面上的示例演示了这一点(但使用 32 位整数)。