在带有位字段的结构中的偏移
如果我们有一个具有位字段的结构,那么后续成员如何在结构中对齐?考虑以下代码:
If we have a struct with bit fields, then how are the subsequent members aligned in the struct? Consider the following code:
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
struct没有任何填充。但是,在第二种情况下,当位字段溢出4个字节时,在最后(第8个)字节中分配 c
。
Here, in the first case, b
is allocated just in the 2nd byte of the struct without any padding. But, in the 2nd case, when bit fields overflow 4 bytes, c
is allocated in the last (8th) byte.
第二种情况发生了什么?一般来说,在涉及位字段的结构中填充的规则是什么?
What is happening in the 2nd case? What is the rule for padding in structs involving bit fields in general?
成员在结构中对齐?
how are the subsequent members aligned in the struct?
没人知道。这是实现定义的行为,因此是编译器特定的。
Nobody knows. This is implementation-defined behavior and thus compiler-specific.
第二种情况发生了什么?
What is happening in the 2nd case?
编译器可能已经添加了填充字节或填充位。或者结构的位顺序可能与您期望的不同。结构的第一项不一定包含MSB。
The compiler may have added padding bytes or padding bits. Or the bit order of the struct might be different than you expect. The first item of the struct is not necessarily containing the MSB.
一般来说,涉及位字段的结构中的填充规则是什么? / p>
What is the rule for padding in structs involving bit fields in general?
编译器可以随意在结构中的任何位置添加任何类型的填充字节(和位字段中的填充位)因为它不是在结构的开始处。
The compiler is free to add any kind of padding bytes (and padding bits in a bit field), anywhere in the struct, as long as it isn't done at the very beginning of the struct.
位字段被标准定义得很差。它们本质上对于除了在存储器中的随机位置分配的布尔标志的块之外的任何其它事物是无用的。我建议你使用位整数运算符。然后你会得到100%的确定性,可移植代码。
Bit-fields are very poorly defined by the standard. They are essentially useless for anything else but chunks of boolean flags allocated at random places in memory. I would advise you to use bit-wise operators on plain integers instead. Then you get 100% deterministic, portable code.