3

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

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 个)字节中分配。

第二种情况发生了什么?一般来说,在涉及位字段的结构中填充的规则是什么?

4

2 回答 2

2

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

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

第二种情况发生了什么?

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

一般来说,在涉及位字段的结构中填充的规则是什么?

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

标准对位域的定义非常差。除了分配在内存中随机位置的布尔标志块之外,它们基本上对其他任何东西都没有用。我建议您改为对纯整数使用按位运算符。然后,您将获得 100% 确定性、可移植的代码。

于 2013-10-15T06:41:29.417 回答
-1

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

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

谢谢

一些参考::

数据结构对齐-维基百科

于 2013-10-15T06:52:00.600 回答