有效使用位域和联合

时间:2018-03-18 17:15:36

标签: c++ unions bit-fields

我写这段代码只是为了它的乐趣:

union {
    struct {
        bool a : 1;
        bool b : 1;
        bool c : 1;
        bool d : 1;
        bool e : 1;
        bool f : 1;
        bool g : 1;
        bool h : 1;
    } a;
    uint8_t b;
} uni {0}; // sets .a bits to false

// union size  : 1 byte

我可以单独切换每个位:

uni.a.a = true;
uni.a.d = true;

cout << bitset<8>(uni.b) << endl; // Prints 000010001

并且还使用位掩码:

uni.b = 0b00001000;

if(uni.a.a) cout << "a";
if(uni.a.b) cout << "b";
if(uni.a.c) cout << "c";
if(uni.a.d) cout << "d";
if(uni.a.e) cout << "e";
if(uni.a.f) cout << "f";
if(uni.a.g) cout << "g";
if(uni.a.h) cout << "h";
// prints 'd'

我知道还有其他方法可以做到这一点(按位操作),但我喜欢这种设计。我的问题是:在可靠性和性能方面,这是否很好地利用了位域和工会?

1 个答案:

答案 0 :(得分:0)

  

我的问题是:在可靠性和性能方面,这是否很好地利用了位域和工会?

就性能而言,你所做的事情可能与它将要获得的一样好,至少在访问位级别的内存方面。

在可靠性方面,大多数现代系统都可以。冒着听起来像语言律师的风险,这里有一些领域可能会有不同的结果:

  1. sizeof(bool)不保证为1,即bool可以存储在大于一个字节的内存中。我不知道bool不是一个字节大小的任何现代系统,但你可以想象一个较旧或较差的实现,使bool的大小与{{1}相同}}。这本来就会甩掉你的int
  2. 访问union的其他成员变量可能导致未定义的行为
  3. 跨系统的字节顺序可能不同(例如,大端或小端),导致union的哪个成员代表MSB的差异。
  4. 从技术上讲,该实现可以在一个字节内以任何顺序布置位字段的各个位。我知道的每个实现都会按照您在union中定义的顺序对它们进行排序,但这不一定要发生。
  5. 实现可以在struct的各个成员之间插入填充,使得各个位在不同的内存字节中。同样,我所知道的所有实现都不会这样做,但它可能会发生。
  6. 我认为你不必担心上述问题。但是,就覆盖可能出错的一切而言,我认为上面的列表很好地涵盖了如果你真的在寻找一个有点不同的实现的话,你可能会遇到的奇怪的场景。