使用位域在标准 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 中的 enums 只不过是调试辅助工具。如果编译器有 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 的标准行为。不可能出现错误,也不会进行超优化。