位域和联合的有效使用
Valid use of bit-fields and unions
我写这段代码只是为了好玩:
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'
我知道还有其他方法可以做到这一点(按位运算),但我喜欢这种设计。我的问题是:就可靠性和性能而言,这是对位域和联合的良好使用吗?
My question is: is this a good use of bitfields and unions, in terms of reliability and performance?
就性能而言,您正在做的事情可能与将要达到的一样好,至少在位级别访问内存方面是这样。
就可靠性而言,它可能适用于大多数现代系统。冒着听起来像语言律师的风险,以下是一些可能在不同系统中产生不同结果的领域:
sizeof(bool)
不保证为1,即bool
可以存储在大于一个字节的内存中。我不知道有哪个现代系统 bool
不是一个字节的大小,但你可以想象一个旧的或错误的实现使得 bool
与 [=14] 的大小相同=].这本质上会影响你的 union
.
- 访问
union
的不同成员变量会导致未定义的行为
- 跨系统的字节顺序可能不同(例如,大端或小端),导致
union
的成员代表 MSB 的差异。
- 从技术上讲,该实现可以在一个字节内以任何顺序布置位域的各个位。我知道的每个实现都会按照您在
struct
中定义的顺序对它们进行排序,但这不一定会发生。
- 该实现可以在
struct
的各个成员之间插入填充,以便各个位位于内存的不同字节中。同样,我所知道的所有实现都不会这样做,但它可能会发生。
我认为您不必担心上述问题。但是,就涵盖所有可能出错的内容而言,我认为上面的列表很好地涵盖了真正 odd-ball 如果您真的搜索有点不同的实现可能会遇到的情况。
我写这段代码只是为了好玩:
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'
我知道还有其他方法可以做到这一点(按位运算),但我喜欢这种设计。我的问题是:就可靠性和性能而言,这是对位域和联合的良好使用吗?
My question is: is this a good use of bitfields and unions, in terms of reliability and performance?
就性能而言,您正在做的事情可能与将要达到的一样好,至少在位级别访问内存方面是这样。
就可靠性而言,它可能适用于大多数现代系统。冒着听起来像语言律师的风险,以下是一些可能在不同系统中产生不同结果的领域:
sizeof(bool)
不保证为1,即bool
可以存储在大于一个字节的内存中。我不知道有哪个现代系统bool
不是一个字节的大小,但你可以想象一个旧的或错误的实现使得bool
与 [=14] 的大小相同=].这本质上会影响你的union
.- 访问
union
的不同成员变量会导致未定义的行为 - 跨系统的字节顺序可能不同(例如,大端或小端),导致
union
的成员代表 MSB 的差异。 - 从技术上讲,该实现可以在一个字节内以任何顺序布置位域的各个位。我知道的每个实现都会按照您在
struct
中定义的顺序对它们进行排序,但这不一定会发生。 - 该实现可以在
struct
的各个成员之间插入填充,以便各个位位于内存的不同字节中。同样,我所知道的所有实现都不会这样做,但它可能会发生。
我认为您不必担心上述问题。但是,就涵盖所有可能出错的内容而言,我认为上面的列表很好地涵盖了真正 odd-ball 如果您真的搜索有点不同的实现可能会遇到的情况。