最小位域大小
Smallest size of bit field
我在理解 sizeof 返回的结果时遇到一些问题。
假设我有两个结构:
typedef struct{
unsigned int age : 4;
unsigned char gender : 1;
unsigned int size : 2;
} child_t;
typedef struct{
unsigned int age : 4;
unsigned char gender : 1;
unsigned int size : 2;
} __attribute__((packed)) child_t_packed;
https://coliru.stacked-crooked.com/view?id=10866c66fe82f4e4
你能解释一下为什么第一个结构的大小是 4 个字节吗?
可能我错了,但我预计是 2 个字节。 (第一行4位,第二行3位)。
打包版本忽略对齐,在第二种情况下sizeof(child_t_packed) = 1 byte.
这是否意味着 1 个字节是 child_t_packed 类型的变量在内存中可能占用的最小大小?或者最小值可以是 7 位?
在标准 C++ 中,结构的最小可能大小为 1 char
(至少 8 位)。因此,即使像 __attribute__((packed))
这样的扩展也被迫产生大小为 1.
的结构
此外,几乎所有关于位域布局的内容都是实现定义的。
在这个例子中,GCC 似乎只是选择最大指定成员类型 (int
) 的对齐方式来进行位域对齐。
如果将 int
更改为 short
,则 sizeof(child_t)
将产生 2
:
typedef struct{
unsigned short age : 4;
unsigned char gender : 1;
unsigned short size : 2;
} child_t;
child_t
的大小是四个字节,因为实现决定将 struct
与 unsigned int
对齐,即 age
和 [=15] 的类型=].
Allocation of bit-fields within a class object is implementation-defined. Alignment of bit-fields is implementation-defined. Bit-fields are packed into some addressable allocation unit.
如果 child_t
仅由 unsigned char
位域成员组成,则对齐将是 unsigned char
的对齐,而整个 struct
将(很可能,它仍然是实现定义的)适合单个字节。
typedef struct{
unsigned char age : 4;
unsigned char gender : 1;
unsigned char size : 2;
} child_t_char;
见https://godbolt.org/z/MGKPqGPKq
child_t_packed
的大小为 1
,因为我们使用 packed
属性强制执行最小填充。
The packed
attribute specifies that a structure member should have the smallest possible alignment—one bit for a bit-field and one byte otherwise, unless a larger value is specified with the aligned attribute. The attribute does not apply to non-member objects.
见GCC 11 documentation on variable attributes
由于4+1+2位可以放入一个字节,所以大小为1
。这意味着 child_t_packed
类型的对象将在内存中占用 正好 个字节。
我在理解 sizeof 返回的结果时遇到一些问题。
假设我有两个结构:
typedef struct{
unsigned int age : 4;
unsigned char gender : 1;
unsigned int size : 2;
} child_t;
typedef struct{
unsigned int age : 4;
unsigned char gender : 1;
unsigned int size : 2;
} __attribute__((packed)) child_t_packed;
https://coliru.stacked-crooked.com/view?id=10866c66fe82f4e4
你能解释一下为什么第一个结构的大小是 4 个字节吗?
可能我错了,但我预计是 2 个字节。 (第一行4位,第二行3位)。
打包版本忽略对齐,在第二种情况下sizeof(child_t_packed) = 1 byte.
这是否意味着 1 个字节是 child_t_packed 类型的变量在内存中可能占用的最小大小?或者最小值可以是 7 位?
在标准 C++ 中,结构的最小可能大小为 1 char
(至少 8 位)。因此,即使像 __attribute__((packed))
这样的扩展也被迫产生大小为 1.
此外,几乎所有关于位域布局的内容都是实现定义的。
在这个例子中,GCC 似乎只是选择最大指定成员类型 (int
) 的对齐方式来进行位域对齐。
如果将 int
更改为 short
,则 sizeof(child_t)
将产生 2
:
typedef struct{
unsigned short age : 4;
unsigned char gender : 1;
unsigned short size : 2;
} child_t;
child_t
的大小是四个字节,因为实现决定将 struct
与 unsigned int
对齐,即 age
和 [=15] 的类型=].
Allocation of bit-fields within a class object is implementation-defined. Alignment of bit-fields is implementation-defined. Bit-fields are packed into some addressable allocation unit.
如果 child_t
仅由 unsigned char
位域成员组成,则对齐将是 unsigned char
的对齐,而整个 struct
将(很可能,它仍然是实现定义的)适合单个字节。
typedef struct{
unsigned char age : 4;
unsigned char gender : 1;
unsigned char size : 2;
} child_t_char;
见https://godbolt.org/z/MGKPqGPKq
child_t_packed
的大小为 1
,因为我们使用 packed
属性强制执行最小填充。
The
packed
attribute specifies that a structure member should have the smallest possible alignment—one bit for a bit-field and one byte otherwise, unless a larger value is specified with the aligned attribute. The attribute does not apply to non-member objects.
见GCC 11 documentation on variable attributes
由于4+1+2位可以放入一个字节,所以大小为1
。这意味着 child_t_packed
类型的对象将在内存中占用 正好 个字节。