我可以遊移,然後分配,然後再做出調整,但它意味着 一旦有人改變位字段的順序,代碼 破....
不,這不是代表代碼被破壞了。你可以改變任何(以任意順序/你可以把其中的一些未設置),你喜歡
在您的示例位字段:
S s;
s.flag2bits = 2;
s.flag1bit = 1;
更改flag2bits
不會影響存儲在flag1bit
值。
但是,您的問題可能與您在struct
中持有的union
有關。更改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。雖然至少在鏗鏘-3.5,上面的代碼將打印:
21
01
這說明我試圖讓點(即工會領域的覆蓋)。
我會考慮從您的struct S
代碼中刪除union
,儘管我可能沒有看到您想要實現的全貌。
寫入一個位域不會與其他位混淆,這會使位域絕對無用 - http://coliru.stacked-crooked.com/a/3bbf315576887706 – Praetorian
@Praetorian除非有多個線程。 –
@AlanStokes有關C++行爲的每個聲明隱含地具有「除非存在未定義的行爲」 –