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

时间:2014-11-03 17:48:53

标签: c bit-fields

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

将其付诸实践,假设int是2个字节(16位),而short是1个字节(8位)以节省输入。另外,假设我们正在使用gcc编译器(很好地解释了与clang的差异)。

struct foo {
    unsigned int a:5;
    unsigned int :0;
    unsigned int b:3;
}

在内存中,这看起来像

struct address
   |            
   |
   v
   aaaaa000 00000000 bbb00000 00000000

问题1:根据我的理解,看起来像aaaaa000 00000000 0..00bbb00000...,因此bbb必须在当前跟随直接与对齐容器。这是真的吗?

继续,如果我指定

struct bar {
    unsigned short x:5; 
    unsigned int :0;
    unsigned short y:7;
}

会是这样吗?

struct address
   | short stops here         short starts  
   |      |                   |   
   v      v | this is uint  | v              
   xxxxx000 00000000 00000000 yyyyyyy0

修改1 有人指出,短路不能少于16个字节。这与这个问题的观点略有不同。但是,如果它对您很重要,您可以将short替换为char,将int替换为short

2 个答案:

答案 0 :(得分:1)

阅读文字in context后更新:

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

struct bar {
    unsigned char x:5; 
    unsigned int :0;
    unsigned char y:7;
}

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

 char pad pad      int boundary
  |    |   |        |
  v    v   v        v       
  xxxxx000 00000000 yyyyyyy0

(我忽略了endian)。

零长度位域使位置移动到下一个int边界。您将int定义为16位,因此16减5给出11位填充。

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

答案 1 :(得分:-1)

首先,每当编写位字段时,始终建议您以使用的数据类型的升序或降序大小声明变量。这样编译器总是选择最高的数据类型大小,并且它会生成相同大小的块。

这就是我的想法。

struct address
| short stops here         short starts  
|    |                   |   
v   v| this is unit      | v              
xxxxx000 00000000 00000000 yyyyyyy0