我写这段代码只是为了它的乐趣:
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'
我知道还有其他方法可以做到这一点(按位操作),但我喜欢这种设计。我的问题是:在可靠性和性能方面,这是否很好地利用了位域和工会?
答案 0 :(得分:0)
我的问题是:在可靠性和性能方面,这是否很好地利用了位域和工会?
就性能而言,你所做的事情可能与它将要获得的一样好,至少在访问位级别的内存方面。
在可靠性方面,大多数现代系统都可以。冒着听起来像语言律师的风险,这里有一些领域可能会有不同的结果:
sizeof(bool)
不保证为1,即bool
可以存储在大于一个字节的内存中。我不知道bool
不是一个字节大小的任何现代系统,但你可以想象一个较旧或较差的实现,使bool
的大小与{{1}相同}}。这本来就会甩掉你的int
。union
的其他成员变量可能导致未定义的行为union
的哪个成员代表MSB的差异。union
中定义的顺序对它们进行排序,但这不一定要发生。struct
的各个成员之间插入填充,使得各个位在不同的内存字节中。同样,我所知道的所有实现都不会这样做,但它可能会发生。我认为你不必担心上述问题。但是,就覆盖可能出错的一切而言,我认为上面的列表很好地涵盖了如果你真的在寻找一个有点不同的实现的话,你可能会遇到的奇怪的场景。