具有位字段的结构中的偏移量

如果我们有一个带有位字段的结构,那么后续成员如何在结构中对齐? 请考虑以下代码:

struct A{ int a:1; char b; // at offset 1 }; struct B{ int a:16; int b: 17; char c; // at offset 7 }; printf("Size of A: %d\n", (int)sizeof(struct A)); printf("Offset of b in A: %d\n", (int)offsetof(struct A, b)); printf("Size of B: %d\n", (int)sizeof(struct B)); printf("Offset of c in B: %d\n", (int)offsetof(struct B, c)); 

输出:

 Size of A: 4 Offset of b in A: 1 Size of B: 8 Offset of c in B: 7 

这里,在第一种情况下, b仅在结构的第二个字节中分配而没有任何填充。 但是,在第二种情况下,当位字段溢出4个字节时, c被分配在最后一个(第8个)字节中。

第二种情况发生了什么? 一般涉及位域的结构中填充的规则是什么?

后续成员如何在结构中对齐?

没人知道。 这是实现定义的行为,因此也是特定于编译器的行为。

第二种情况发生了什么?

编译器可能添加了填充字节或填充位。 或者结构的位顺序可能与您预期的不同。 结构的第一项不一定包含MSB。

一般涉及位域的结构中填充的规则是什么?

编译器可以在结构中的任何位置随意添加任何类型的填充字节(以及位字段中的填充位),只要它不在结构的最开始处完成即可。

标准定义了很少的位域。 除了在内存中随机位置分配的块布尔标志之外,它们对于其他任何东西都是无用的。 我建议你在普通整数上使用逐位运算符。 然后,您将获得100%确定性的可移植代码。

我会举一个小例子。 希望这能说清楚::考虑两种结构:

 struct { char a; int b; char c; } X; 

与。

 struct { char a; char b; int c; } Y; 

关于以下评论的更多解释:

以下所有不是100%,但结构将在32位系统中构建的常见方式,其中int为32位:

结构X:

 | | | | | | | | | | | | | char pad pad pad ---------int---------- char pad pad pad = 12 bytes 

结构Y:

 | | | | | | | | | char char pad pad ---------int---------- = 8 bytes 

谢谢

一些参考::

数据结构Alignment-wikipedia