c - 包含位域的结构的大小

标签 c pointers bit-fields strict-aliasing

我有一个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 intunsigned 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/

相关文章:

C++指针类

c编程数组和指针

c - 在 C 中使用位域的正确方法是什么?

algorithm - 实现动态位域

c - 如何优化我的 C 代码以求解 R 中的二次方程?

C - 函数内的数组初始化

c++ - 为结构成员分配的内存是连续的吗?如果结构成员是数组怎么办?

c++ - C++ 位域为什么以及如何不可移植?

c - 将多维数组作为函数参数传递

c++ - 为什么有人会使用 C 而不是 C++?