位域分配 - 是否安全

Bitfield assignment - is it safe?

本文关键字:安全 是否 分配 位域      更新时间:2023-10-16

我有一个位域中塞满了一堆属性以节省空间:

struct Flags {
    uint access : 2;
    uint status : 2;
    uint isEnabled : 1;
    uint isDeletable: 1;
    ...
};

然后我有一个静态Flags defaultFlags,它在程序启动时初始化。我的主要问题是,为了消除单独分配每个字段的 20 行,在对象构造函数中flags = defaultFlags;是否安全?

另外,我想知道序列化呢?根据编译器的说法,Flags是 4 个字节,我可以将其序列化为 32 位无符号整数并对其进行解密而不会损坏任何数据吗?

我的主要问题是标志 = defaultFlags 是否安全; 在 对象构造函数,以消除用于赋值的 20 行 每个字段单独?

是的。Flags的隐式定义复制构造函数将相应地分配每个位字段。[类副本]/15:

每个基本或非静态数据成员都按以下方式复制/移动 适合其类型:

  • 如果成员是数组,则 [..]
  • 如果成员m具有右值引用类型 T&& [..]
  • 否则,基或成员
  • 使用x的相应
    基或成员直接初始化。

我可以将其序列化为 32 位无符号整数并将其取消灭菌为 这样没有任何数据损坏?

如果您使用相同的编译程序在同一台计算机上写入和读取文件,是的。不过,其他编译器或体系结构的布局可能有所不同,该标准在这方面没有施加任何固定的要求。[class.bit]/1:

类对象中位字段的分配为 实现定义。位字段的对齐方式为 实现定义。位字段被打包到一些可寻址的 分配单元。[ 注意:位域跨分配单元 有些机器而不是其他机器。位字段从右到左分配 在某些计算机上,在其他计算机上从左到右。— 尾注 ]

如果您将其写入大小为 sizeof Fieldchar 数组,将其写入文件并从那里再次提取,将其复制回 Field 对象应该会给您相同的值。[基本类型]/2(强调我的):

对于任何对象(基类子对象除外)的微不足道 可复制类型T,无论对象是否具有有效的类型值 T,可以复制构成对象的基础字节(1.7) 成charunsigned char数组。如果内容charunsigned char数组复制回对象中, 对象随后应保持其原始值。

但是,正如评论中指出的那样,使用位掩码可以实现完全可移植性(和合理的效率)。