【问题标题】:Why can't a bit field be split between different underlying types?为什么不能在不同的基础类型之间拆分位字段?
【发布时间】:2020-12-07 11:04:52
【问题描述】:

为什么这两个结构的大小不同?

#pragma pack(push, 1)
    struct WordA
    {
        uint32_t address           : 8;
        uint32_t data             : 20;
        uint32_t sign              : 1;
        uint32_t stateMatrix : 2;
        uint32_t parity            : 1;
    };

    struct WordB
    {
        uint8_t address;
        uint32_t data             : 20;
        uint8_t sign              : 1;
        uint8_t stateMatrix : 2;
        uint8_t parity            : 1;
    };
#pragma pack(pop)

不知何故,WordB 占用 6 个字节而不是 4 个字节,而 WordA 恰好占用 32 位。 我假设给定结构内已使用位的总和将使两个结构具有相同的大小。显然我错了,但我找不到原因。 Bit fields 页面仅显示所有结构成员都属于同一类型的示例,这是WordA 的情况。

谁能解释一下,为什么尺寸不匹配,是否符合标准或实现定义?

【问题讨论】:

  • 位域是特定于实现的,但通常,位域不会在不同的底层类型之间拆分。
  • @Jarod42 bitfield doesn't split between different underlying types. 我想这可能是原因,但我想参考一下标准。
  • @Jarod42 我已将问题重命名为具体。
  • 编译器应该如何看到它允许加入address 这不是与其余位域的位域?

标签: c++ bit-fields


【解决方案1】:

为什么不能在不同的底层类型之间拆分位域?

在标准允许的意义上可以

不是,因为这是语言实现者(或者更确切地说,ABI 的设计者)选择的。这个决定可能是首选,因为它可以使程序更快或编译器更容易实现。

这是标准报价:

[class.bit]

... 类对象内的位域分配是实现定义的。 位域的对齐是实现定义的。 位域被打包到一些可寻址的分配单元中。

【讨论】:

  • 可以参考一下标准吗?在这种情况下,我会接受你的回答。
  • @SergeyKolesnik 添加了报价。
  • 我认为标准报价证明相反。 bits 字段必须打包到它们的 自己的 可寻址单元中,例如不与非位域 uint8_t address; 重叠的 uint32_t
  • @MSalters 即使​​是位域,它也不会重叠。
  • @SergeyKolesnik:如果它们都是位域,则位本身不会重叠,但位域将从同一个可寻址单元分配。但是在WordB 中,只有24 个uint32_t 位被使用,因此有8 个未使用位。
猜你喜欢
  • 1970-01-01
  • 2013-11-02
  • 2011-12-29
  • 2016-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
相关资源
最近更新 更多