我有一个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
来重置位字段,但我对其他感兴趣可移植方式)。
最佳答案
Is
struct A
guaranteed by the standard to have size 4?
没有。它可能是 4 号,也可能不是。
Is it possible that a compiler instead uses only one byte for struct A since it uses exactly two bits?
是的,这是可能。
I wonder what makes
*(uint32_t*)&b = 0
bad here ...
- 赋值可能不足以将
b
归零。 - 罕见:可选类型
uint32_t
可能不存在。 - 代码存在别名问题。
... and what I should do
要将b
清零,请分配一个为零的struct B
。研究复合文字。。请注意,下面的代码适用于各种类型,而不仅仅是带有位字段的struct
。
b = (struct B){0};
或者,如果您想要一个非零值:
b = (struct B){.a = 0, .c = 42, .b = 1};
位字段很棘手。使用 signed int
、unsigned int
和 _Bool
而不是 uint32_t
以获得最大的可移植性。
A bit-field shall have a type that is a qualified or unqualified version of
_Bool
,signed int
,unsigned int
, or some other implementation-defined type. It is implementation-defined whether atomic types are permitted. C17dr § 6.7.2.1 5
关于c - 包含位域的结构的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71715395/