我有一個struct如下。
struct A {
uint32_t a : 1;
uint32_t b : 1;
};
標準是否struct A保證尺寸為 4?編譯器是否可能只使用一個位元組,struct A因為它恰好使用兩位?
struct B {
uint32_t a : 1;
uint32_t b : 1;
uint32_t c : 30;
} b;
如果我想將位域設定b為零,因為sizeof(struct B) = 4,對我來說這樣做看起來不錯
*(uint32_t*)&b = 0。但是我看到很多關于 SO 的討論認為這種指標轉換是一種不好的做法。我想知道*(uint32_t*)&b = 0這里有什么不好以及我應該怎么做(我知道我可以memset用來重置位域,但我對其他可移植方式感興趣)。
uj5u.com熱心網友回復:
標準是否
struct A保證尺寸為 4?
不,它可能是 4 號,也可能不是。
編譯器是否有可能只使用 struct A 的一個位元組,因為它恰好使用兩位?
是的,這是可能的。
我想知道這里有什么
*(uint32_t*)&b = 0不好...
- 分配可能不足以歸零
b。 - 罕見:可選型別
uint32_t可能不存在。 - 代碼有混疊問題的風險。
...以及我應該怎么做
要歸零b,請分配一個struct B為零的值。研究復合字面。請注意,下面的代碼適用于各種型別,而不僅僅是struct位欄位。
b = (struct B){0};
或者,如果您想要一個非零值:
b = (struct B){.a = 0, .c = 42, .b = 1};
位域很棘手。使用signed int, unsigned intand _Booland notuint32_t以獲得最大的可移植性。
位域的型別應為 、 、 或其他一些實作定義的型別的合格或非
_Bool合格signed int版本unsigned int。是否允許原子型別是實作定義的。C17dr § 6.7.2.1 5
uj5u.com熱心網友回復:
第一個問題,可以加一個alignment,但是這樣會影響執行效率:
#pragma pack(push)
#pragma pack(1)
struct A {
uint32_t a : 1;
uint32_t b : 1;
};
#pragma pack(pop)
第二個問題,可以定義為 union
union B {
struct {
uint32_t a : 1;
uint32_t b : 1;
uint32_t c : 30;
};
uint32_t u;
} b;
// set the bitfields in b to zero
b.u = 0;
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/455286.html
上一篇:重繪令牌對服務器性能的影響
