具有位字段的结构中的偏移量
如果我们有一个带有位字段的结构,那么后续成员如何在结构中对齐? 请考虑以下代码:
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