在使用这个问题中的代码时,我发现当使用8位宽枚举而不是uint8_t类型时,结构的大小会增加。
请参阅以下代码示例:
代码选项A
typedef enum { A, B, C, MAX = 0xFF } my_enum;
struct my_compact_struct_option_a
{
my_enum field1 : 8; // limiting enum size to 8 bits
uint8_t second_element[6];
uint16_t third_element;
};此结构second_element中的第二个变量的偏移量为1。这表明枚举field1仅限于uint8_t大小,但是结构的大小为12字节。这对我来说是意外的。
把这个和
代码选项B
typedef uint8_t my_type;
struct my_compact_struct_option_b
{
my_type field1;
uint8_t second_element[6];
uint16_t third_element;
};在这里,second_element的偏移量也是1,但是这个结构的大小是10字节。这是意料之中的。
为什么第一个代码示例中的结构增加到12个字节?
你总是可以自己试试这段代码的。
发布于 2022-07-25 16:52:56
正如在另一个答案中提到的,C标准指出,实现可以使用任何足够大的存储单元来容纳位字段。由于默认情况下,enum实际上是int,所以大多数编译器都会为位字段使用int大小的存储单元。特别是,gcc和MSVC都将创建一个4字节的enum和一个12字节的struct。
在评论中具体说明的情况下:
struct foo { int a : 8; char b; };gcc和clang给它的大小为4,而MSVC给它的大小为8。
因此,似乎正在发生的是,a驻留在一个int大小的存储单元中,因为这是位字段的基本类型。结构的对齐是4,因为这是最大字段的大小,特别是容纳位字段的int大小单元。
gcc和clang似乎与MSVC不同之处在于,gcc和clang将允许非位字段占用与位字段相同的存储单元,而MSVC则将比特字段保留在它们自己的存储单元中。
如果您想使enum类型更小,有一些实现的特定方法。
在gcc中,use可以使用packed属性:
typedef enum __attribute__((__packed__)) { A, B, C, MAX = 0xFF } my_enum;也可以传递-fshort-enums标志以缩小所有枚举的大小。这两种方法都会导致my_enum大小为1字节,struct my_compact_struct_option_a为10字节。
clang允许您使用以下语法指定枚举的大小:
typedef enum : char { A, B, C, MAX = 0xFF } my_enum;https://stackoverflow.com/questions/73047713
复制相似问题