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

时间:2013-10-09 14:38:40

标签: 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;
}

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

5 个答案:

答案 0 :(得分:2)

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

是。

检查byte offsetbit offset

但是,根据有效的对齐方式,包含位字段的聚合的对齐规则会有所不同 enter image description here

这些规则是described Here

答案 1 :(得分:1)

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

布局可能类似于以下内容(不完全按比例):

bf_struct1

+---------------+---------+---------+-----------------------------------+
|    uint8_t    | uint8_t | Padding | uint64_t                          |
+---------------+---------+---------+-----------------------------------+
| bf1, bf2, bf3           | 48-bits | bf4                               |
+---------------+---------+---------+-----------------------------------+

bf_struct2

+-----------------------------------+
|      uint64_t                     |
+-----------------------------------+
| bf1, bf2, bf3, bf4                |
+-----------------------------------+

答案 2 :(得分:1)

#include <stdio.h>

#define uint64_t unsigned long long
#define uint8_t unsigned char

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;
};
int main(){
    printf("%lu ", sizeof(struct bf_struct1));
    printf("%lu ", sizeof(struct bf_struct2));
    return 0;
}

结果8 16.所以我会说答案是肯定的。编译器依赖甚至 虽然gcc和clang同意我的机器。你可以做一些工会和 弄清楚对齐是什么。

答案 3 :(得分:1)

  • 整个位字段的对齐是未指定的行为,并且是否允许位字段分配未对齐是实现定义的行为。
  • 位字段的位顺序是实现定义的。
  • 由于上面的两个评论,编译器可以自由地在位字段内的任何位置添加填充位和填充字节,因为它可以以实现定义的方式。
  • 是否实际允许uint64_t在位字段内是实现定义的。所以代码甚至可能都不起作用。

实际上没有办法告诉这个代码甚至会做什么,更不用说它如何受到对齐的影响,而不需要阅读特定编译器的文档。

答案 4 :(得分:1)

来自horse's mouth

6.7.2.1结构和联合说明符
...
5位字段的类型应为_Bool, signed int, unsigned int的限定或非限定版本,或其他一些实现定义的类型。它是 实现 - 定义是否允许原子类型 ...
11实现可以分配任何足够大的可寻址存储单元来保存位域。 如果剩余足够的空间,则紧跟在a中的另一个位字段的位字段 结构应打包到同一单元的相邻位。如果剩余空间不足, 是否将不适合的位域放入下一个单元或重叠相邻单元 实现定义。单位内位域分配的顺序(高位到 实现定义的是低阶或低阶到高阶。对齐 可寻址存储单元未指定。

简短的回答:它可以,取决于实施。