C 位字段的类型是否影响结构对齐

C 位字段的类型是否影响结构对齐,c,bit,C,Bit,我有以下结构: struct bf_struct1 { uint64_t bf1 : 1; uint64_t bf2 : 6; uint64_t bf3 : 2; uint64_t bf4 : 55; } struct bf_struct2 { uint8_t bf1 : 1; uint8_t bf2 : 6; uint8_t bf3 : 2; uint64_t bf4 : 55; } 结构成员对齐是否取决于位字段成员的类型?是

我有以下结构:

struct bf_struct1
{
    uint64_t bf1 : 1;
    uint64_t bf2 : 6;
    uint64_t bf3 : 2;
    uint64_t bf4 : 55;
}

struct bf_struct2
{
    uint8_t bf1 : 1;
    uint8_t bf2 : 6;
    uint8_t bf3 : 2;
    uint64_t bf4 : 55;
}

结构成员对齐是否取决于位字段成员的类型?

是的,它会影响它。在第一个给定的示例中,所有字段都可以放入单个64位
uint64-t
,因此该结构可能总共需要8个字节。但对于第二个,它可能总共有16个字节。前三个字段至少需要两个字节(两个
uint8\u t
)。然后,55位的最后一位字段将采用单个
uint64\t
,该字段可能在8字节边界上对齐。因此,虽然实际布局取决于编译器,但在两个示例中,位的位置将不同(因为在第二个示例中,
uint64\t
之前假定了填充)

布局可能如下所示(不完全按比例):

bf_结构1

+---------------+---------+---------+-----------------------------------+
|    uint8_t    | uint8_t | Padding | uint64_t                          |
+---------------+---------+---------+-----------------------------------+
| bf1, bf2, bf3           | 48-bits | bf4                               |
+---------------+---------+---------+-----------------------------------+
bf_结构2

+-----------------------------------+
|      uint64_t                     |
+-----------------------------------+
| bf1, bf2, bf3, bf4                |
+-----------------------------------+
#包括
#定义uint64_t无符号长
#定义uint8_t无符号字符
结构bf_结构1
{
uint64_t bf1:1;
uint64_t bf2:6;
uint64_t bf3:2;
uint64_t bf4:55;
};
结构bf_结构2
{
uint8_t bf1:1;
uint8_t bf2:6;
uint8_t bf3:2;
uint64_t bf4:55;
};
int main(){
printf(“%lu”,sizeof(struct bfu struct1));
printf(“%lu”,sizeof(struct bfu struct2));
返回0;
}
结果是816。所以我会说答案是肯定的。甚至依赖于编译器 虽然gcc和clang在我的机器上达成一致,但你可以建立一些工会和 弄清楚路线到底是什么

Does the structure member alignment depend on type of a bitfield members?  

检查
字节偏移量
位偏移量

但是,根据有效的对齐模式,包含位字段的聚合的对齐规则不同。

这些规则是。

  • 整个位字段的对齐是未指定的行为,是否允许位字段分配未对齐是实现定义的行为
  • 位字段的位顺序由实现定义
  • 由于上面的两条注释,编译器可以随意地以实现定义的方式在位字段中的任意位置添加填充位和填充字节
  • 位字段中是否真正允许uint64_t是由实现定义的,因此代码甚至可能无法工作
如果不阅读特定编译器的文档,就无法判断此代码将做什么,更不用说对齐将如何影响它了。

来自:

6.7.2.1结构和联合规范

5位字段的类型应为合格或不合格版本的
\u Bool、
有符号整数
、无符号整数
,或其他实现定义的类型 实现定义了是否允许原子类型。

11一个实现可以分配任何足够大的可寻址存储单元来容纳一个位字段。 如果剩余的空间足够大,则表示一个位字段,该位字段紧跟在另一个位字段之后 结构应装入同一单元的相邻位中。如果剩余空间不足, 是否将不适合的位字段放入下一个单元或与相邻单元重叠是不确定的 实现定义。单位内位字段的分配顺序(从高阶到低阶) 低阶或低阶到高阶)是实现定义的 未指定可寻址存储单元。
简短回答:可以,具体取决于实现。

sizeof()对这两个结构告诉了您什么?如果它们都是8,我会回答“否”。对于每个编译器,对于每个系统,这都是不同的。位字段在标准中的定义非常糟糕。
Does the structure member alignment depend on type of a bitfield members?