成员数多于其大小的位域联合的大小
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 存储在内存中。
- m.a1 会成为 0xd 或 oxa 的一部分吗?
- 它是 0xd(或 0xa)的第 3 位还是第 0 位?
@tkausl 是正确的。在 union
中,每个成员都与内存中的所有其他成员重叠。因此,根据每个字段中的位数和平台的字节顺序,位字段中的每个字段都会与其他字段重叠。例如,a1
和 a10
可能总是具有相同的值。
由于所有字段在内存中都是重叠的,因此您只需要保存 最长 字段所需的字节数。因为一个字节就够了,那就是 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 定义的字节序和编译器定义的高位或低位赋值。您还可以在位域之间进行填充,以及它们是否跨越相邻单元以实现位域的实现定义细节。
#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 存储在内存中。
- m.a1 会成为 0xd 或 oxa 的一部分吗?
- 它是 0xd(或 0xa)的第 3 位还是第 0 位?
@tkausl 是正确的。在 union
中,每个成员都与内存中的所有其他成员重叠。因此,根据每个字段中的位数和平台的字节顺序,位字段中的每个字段都会与其他字段重叠。例如,a1
和 a10
可能总是具有相同的值。
由于所有字段在内存中都是重叠的,因此您只需要保存 最长 字段所需的字节数。因为一个字节就够了,那就是 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 定义的字节序和编译器定义的高位或低位赋值。您还可以在位域之间进行填充,以及它们是否跨越相邻单元以实现位域的实现定义细节。