配置此语句零宽度位字段可以使下一个字段在下一个容器边界上对齐,其中容器的大小与位字段的基础类型相同
将其付诸实践,假设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
答案 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