成员数多于其大小的位域联合的大小

Size of bit-field union which has more members than its size

#include <stdio.h>

union mix {
  unsigned char a1:1;  
  unsigned char a2:4;
  unsigned char a3:4;    
  unsigned char a4:1;  
  unsigned char a5:4;
  unsigned char a6:4;    
  unsigned char a7:1;  
  unsigned char a8:4;
  unsigned char a9:4;    
  unsigned char a10:1;  
  unsigned char a11:4;
  unsigned char a12:4;       
};

int main() {

    printf("Sizeof mix = %d bytes\n", sizeof(union mix));

    return 0;
}

输出为1字节

超过 8 位的位域成员会怎样?显然我仍然可以为任何位域成员设置和获取正确的值。

更新

感谢您消除我的困惑。一方面的问题:这些位以什么顺序存储在内存中?假设它是小端内存,那么 0xabcd 将作为 0xd、0xc、0xb、0xa 存储在内存中。

  1. m.a1 会成为 0xd 或 oxa 的一部分吗?
  2. 它是 0xd(或 0xa)的第 3 位还是第 0 位?

@tkausl 是正确的。在 union 中,每个成员都与内存中的所有其他成员重叠。因此,根据每个字段中的位数和平台的字节顺序,位字段中的每个字段都会与其他字段重叠。例如,a1a10 可能总是具有相同的值。

由于所有字段在内存中都是重叠的,因此您只需要保存 最长 字段所需的字节数。因为一个字节就够了,那就是 union.

的大小

位以什么顺序存储在内存中?

实现定义。

根据 6.7.2.1 结构和联合说明符the C Standard 的第 11 段:

An implementation may allocate any addressable storage unit large enough to hold a bit- field. If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit. If insufficient space remains, whether a bit-field that does not fit is put into the next unit or overlaps adjacent units is implementation-defined. The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined. The alignment of the addressable storage unit is unspecified.

不同的编译器可以不同地实现位域。请注意,高阶和低阶与大端或小端不同。 8 位 unsigned char 的低位是在打开和关闭时将 1 添加到它的值的那个。同一个 8 位的高位 unsigned char 是翻转时其值加 128 的位。

因此位域有两个级别的实现定义顺序:platform/hardware 定义的字节序和编译器定义的高位或低位赋值。您还可以在位域之间进行填充,以及它们是否跨越相邻单元以实现位域的实现定义细节。