位字段并集的大小,其成员数多于其大小

时间:2016-10-12 18:50:02

标签: c unions

#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 OR oxa的一部分吗?
  2. 是0xd(或0xa)的第3位还是第0位?

2 个答案:

答案 0 :(得分:5)

@tkausl是对的。在union中,每个成员与内存中的所有其他成员重叠。因此,取决于每个字段中的比特数和平台的字节顺序,位域中的每个字段与其他字段重叠。例如,a1a10可能总是具有相同的值。

由于所有字段都在内存中重叠,因此只需要保存最长字段所需的字节数。由于一个字节将执行此操作,因此大小为union

答案 1 :(得分:3)

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

这是实现定义。

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

  

实现可以分配任何可寻址的存储单元   足以容纳一个位域。如果剩余足够的空间,则为比特字段   紧跟在结构中的另一个位域之后应该是   打包到同一单元的相邻位。如果空间不足   仍然存在,是否存在不适合的位域   下一个单位或相邻单位重叠   实现定义。 位域分配的顺序   在单位内(从高阶到低阶或从低阶到高阶)   是实现定义的。可寻址的对齐方式   存储单元未指定。

不同的编译器可以不同地实现位域。请注意,高阶和低阶与big-endian或little-endian不同。 8位unsigned char的低位是在其打开和关闭时将1添加到其值的位。相同的8位unsigned char的高位是在其打开时将其值加128的位。

因此,位字段具有两个级别的实现定义顺序:平台/硬件定义的字节顺序和编译器定义的高阶或低阶分配。您还可以在位字段之间填充,以及它们是否跨越相邻单元到实现定义的位域细节。