我们说我有以下
struct S {
union {
uint8_t flags;
struct {
uint8_t flag2bits : 2;
uint8_t flag1bit : 1;
};
};
};
S s;
s.flag2bits = 2;
s.flag1bit = 1; // this will wipe out the values of other bits
在不影响其他位字段的情况下,为特定位分配值的最佳方法是什么?
我可以转移然后再分配然后再移动但这意味着一旦有人改变了位字段的顺序,代码就会被破坏....
答案 0 :(得分:4)
我可以转移然后再分配,然后再移动,但这意味着 一旦有人改变了位字段的顺序,代码就是 碎....
不,这并不意味着代码被破坏了。您可以更改任何位域(按任何顺序/您可以保留其中一些未设置)
在你的例子中:
S s;
s.flag2bits = 2;
s.flag1bit = 1;
更改flag2bits
不会影响flag1bit
中存储的值。
但是,您的问题可能与union
中的struct
有关。更改 flags
变量将影响这两个位域,因为您将它们存储在单独的struct
中。
我希望这个例子可以解释这个案例:
#include <iostream>
#include <cstdint>
struct S {
union {
uint8_t flags;
struct {
uint8_t flag2bits : 2;
uint8_t flag1bit : 1;
};
};
};
int main(int argc, char *argv[]) {
S s;
s.flag2bits = 2;
s.flag1bit = 1;
std::cout << int(s.flag2bits) << int(s.flag1bit) << std::endl;
s.flags = 4; // As you are using union, at this point you are overwriting
// values stored in your (nested) struct
std::cout << int(s.flag2bits) << int(s.flag1bit) << std::endl;
return 0;
}
编辑:正如@ M.M指出的那样,it's undefined behavior to read from the member of the union that wasn't most recently written。虽然至少在clang-3.5上,上面的代码会打印出来:
21
01
说明了我想要做的一点(即覆盖联合字段)。
我会考虑从您的union
代码中移除struct S
,但我可能看不到您要实现的目标的全貌。
答案 1 :(得分:1)
C ++编译器将为您管理这些位。您可以根据需要设置值。只会设置适当的位。
你试过吗?