位域分配 - 安全吗?

时间:2014-11-18 16:00:41

标签: c++ serialization variable-assignment bit-fields mass-assignment

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

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

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

另外,我想知道序列化怎么样?根据编译器,Flags是4个字节,我可以将其序列化为32位无符号整数并在没有任何数据损坏的情况下对其进行消毒吗?

1 个答案:

答案 0 :(得分:3)

  

我的主要问题是flag = defaultFlags是否安全;在里面   对象构造函数,以消除20行分配   每个领域单独?

是。 Flags的隐式定义的复制构造函数将适当地分配每个Bitfield。 [class.copy] / 15:

  

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

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

  

我可以将其序列化为32位无符号整数并将其去除   没有任何数据损坏?

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

  

类对象中位域的分配是   实现定义。位域的对齐是   实现定义。比特字段被打包成一些可寻址的字段   分配单位。 [注意:比特字段跨越分配单元   一些机器而不是其他机器。位字段从右到左分配   在某些机器上,从左到右在其他机器上。 - 结束记录]

如果将其写入大小为char的{​​{1}}数组,请将其写入文件并再次从中提取,将其复制回sizeof Field对象应该会给您相同的价值观。 [basic.types] / 2(强调我的):

  

对于任何简单的对象(基类子对象除外)   可复制类型Field,无论对象是否包含有效的类型值   T,可以复制构成对象的基础字节(1.7)   成为Tchar的数组。如果的内容   将unsigned charchar的数组复制回对象中   对象随后应保持其原始值。

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