使用位域在标准 C 中将枚举字段强制为 8 位
Forcing enum field to 8 bits in standard C with bitfields
我在这里看到几个关于如何将枚举强制为 8 位或 16 位的问题。常见的答案是它可以在 C++11 或更高版本中完成。不幸的是,我没有那么奢侈。
所以,这就是我的想法。当枚举位于我想要最小化其大小的结构中时,我只需要枚举为 8 位。所以:
选项A:
typedef enum { A, B, C, MAX = 0xFF } my_enum;
struct my_compact_struct
{
my_enum field1 : 8; // Forcing field to be 8 bits
uint8_t something;
uint16_t something_else;
};
我认为大多数或所有优化器都应该足够聪明,能够有效地处理 8 位字段。
选项 B:
不使用枚举。请改用 typedef 和常量。
typedef uint8_t my_type;
static const my_type A = 0;
static const my_type B = 1;
static const my_type C = 2;
struct my_compact_struct
{
my_type field1;
uint8_t something;
uint16_t something_else;
};
选项 A 目前已实施并且似乎有效,但由于我想(现在和将来)做现在正确的事情,而不仅仅是有效的事情,我想知道选项 B 是否明显更好。
谢谢,
如果 enum
中的特定值可以适合比 int
更小的类型,那么 C 实现可以自由选择 enum
的基础类型比 int
更小的类型(但在这种情况下 enum
常量的类型将是 int
)。但是 没有办法 可以强制 C 编译器使用小于 int
的类型。因此,考虑到这一点以及 int
至少是 16 位的事实,你运气不好。
但是 C 中的 enum
s 只不过是调试辅助工具。如果编译器有 uint8_t
类型,只需使用它:
static const uint8_t something = /*some value*/
如果不是,则使用 char
和 希望 CHAR_BIT 是 8。
选项B最好。您会将相关类型定义为已知大小,并且您定义的 const
值也将是正确的大小。
虽然您会丢失 enum
的隐式编号,但字段的显式大小及其值弥补了这一点。
您可以使用 enum
甚至 typedef enum
作为分组 #define
。不要实际将结构成员、数据流或全局变量定义为 enum
类型。而是将所有存储成员定义为固定类型,如 uint8_t
。就像您使用 #define
一样,只需将它们设置为 enum
文字常量。如果您使用任何类型的 lint 工具,那么这种设计风格将引发一些您需要定制的消息。就像 malformed #define
一样,如果文字值不合适,就会发生不好的事情,无论哪种方式都需要注意。在调试器或硬件模拟器中,enum
可以提供有用的显示参考信息。临时变量是全局定义处理方式的一个例外。对于函数参数或自动变量,只有这样,才用 enum
类型定义它们。在这种情况下,int
将是最有效的单词大小以及 enum
的标准行为。不可能出现错误,也不会进行超优化。
我在这里看到几个关于如何将枚举强制为 8 位或 16 位的问题。常见的答案是它可以在 C++11 或更高版本中完成。不幸的是,我没有那么奢侈。
所以,这就是我的想法。当枚举位于我想要最小化其大小的结构中时,我只需要枚举为 8 位。所以:
选项A:
typedef enum { A, B, C, MAX = 0xFF } my_enum;
struct my_compact_struct
{
my_enum field1 : 8; // Forcing field to be 8 bits
uint8_t something;
uint16_t something_else;
};
我认为大多数或所有优化器都应该足够聪明,能够有效地处理 8 位字段。
选项 B:
不使用枚举。请改用 typedef 和常量。
typedef uint8_t my_type;
static const my_type A = 0;
static const my_type B = 1;
static const my_type C = 2;
struct my_compact_struct
{
my_type field1;
uint8_t something;
uint16_t something_else;
};
选项 A 目前已实施并且似乎有效,但由于我想(现在和将来)做现在正确的事情,而不仅仅是有效的事情,我想知道选项 B 是否明显更好。
谢谢,
如果 enum
中的特定值可以适合比 int
更小的类型,那么 C 实现可以自由选择 enum
的基础类型比 int
更小的类型(但在这种情况下 enum
常量的类型将是 int
)。但是 没有办法 可以强制 C 编译器使用小于 int
的类型。因此,考虑到这一点以及 int
至少是 16 位的事实,你运气不好。
但是 C 中的 enum
s 只不过是调试辅助工具。如果编译器有 uint8_t
类型,只需使用它:
static const uint8_t something = /*some value*/
如果不是,则使用 char
和 希望 CHAR_BIT 是 8。
选项B最好。您会将相关类型定义为已知大小,并且您定义的 const
值也将是正确的大小。
虽然您会丢失 enum
的隐式编号,但字段的显式大小及其值弥补了这一点。
您可以使用 enum
甚至 typedef enum
作为分组 #define
。不要实际将结构成员、数据流或全局变量定义为 enum
类型。而是将所有存储成员定义为固定类型,如 uint8_t
。就像您使用 #define
一样,只需将它们设置为 enum
文字常量。如果您使用任何类型的 lint 工具,那么这种设计风格将引发一些您需要定制的消息。就像 malformed #define
一样,如果文字值不合适,就会发生不好的事情,无论哪种方式都需要注意。在调试器或硬件模拟器中,enum
可以提供有用的显示参考信息。临时变量是全局定义处理方式的一个例外。对于函数参数或自动变量,只有这样,才用 enum
类型定义它们。在这种情况下,int
将是最有效的单词大小以及 enum
的标准行为。不可能出现错误,也不会进行超优化。