【问题标题】:Does the type of bitfield affect structure alignement位域的类型是否影响结构对齐
【发布时间】:2013-10-16 23:50:48
【问题描述】:

我有以下结构:

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;
}

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

【问题讨论】:

  • sizeof() 告诉你这两个结构的什么?如果他们都是 8 岁,我会回答“不”。

标签: c bit


【解决方案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 同意我的机器。你可以建立一些工会和 弄清楚到底是什么对齐方式。

【讨论】:

  • 这对于每个编译器和每个系统都会有所不同。位域在标准中的定义极差。
【解决方案2】:
  • 位域整体对齐是未指定行为,是否允许位域分配未对齐是实现定义的行为。
  • 位字段的位顺序是实现定义的。
  • 由于上述两点,编译器可以按照实现定义的方式随意在位字段内的任何位置添加填充位和填充字节。
  • uint64_t 是否实际允许在位字段中由实现定义。所以代码甚至可能无法正常工作。

如果不阅读特定编译器的文档,真的无法知道这段代码会做什么,更不用说它会如何受到对齐的影响。

【讨论】:

    【解决方案3】:
    Does the structure member alignment depend on type of a bitfield members?  
    

    是的。

    检查byte offsetbit offset

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

    这些规则是described Here

    【讨论】:

      【解决方案4】:

      来自horse's mouth

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

      简短的回答:它可以,具体取决于实现。

      【讨论】:

        【解决方案5】:

        是的,它会影响它。在第一个给出的示例中,所有字段都可以放入单个 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                |
        +-----------------------------------+
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-04-05
          • 1970-01-01
          • 1970-01-01
          • 2018-03-07
          • 2012-03-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多