使用位域强制枚举字段在标准C中为8位

时间:2017-01-25 14:06:57

标签: c enums bit-fields

我在这里看到几个关于如何强制枚举为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和constants。

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是否正确显然更好。

谢谢,

3 个答案:

答案 0 :(得分:4)

如果enum中的特定值可以适合比int更小的类型,那么C实现可以自由选择enum的基础类型为更小类型而不是int(但在这种情况下,enum常量的类型将为int)。但是无法可以强制C编译器使用小于int的类型。因此,考虑到这一点以及int至少为16位的事实,你运气不好。

但是C中的enum只不过是调试辅助工具。如果你有编译器,只需使用uint8_t类型:

static const uint8_t something = /*some value*/

如果没有,请使用char希望 CHAR_BIT为8。

答案 1 :(得分:2)

选项B最好。您可以将相关类型定义为已知大小,并且您定义的const值也将是正确的大小。

虽然您会失去enum的隐式编号,但字段及其值的显式大小可以弥补它。

答案 2 :(得分:0)

您可以像分组enum一样使用typedef enum甚至#define。实际上,请勿将结构成员,数据流或全局变量定义为类型enum。而是将所有存储成员都定义为固定类型,例如uint8_t。就像您使用#define一样,只需将它们设置为enum文字常量。如果您使用任何种类的皮棉工具,则此设计样式将产生一些您需要定制的消息。就像格式错误的#define一样,如果字面值不合适,那么可能会发生坏事,无论哪种方式都需要引起注意。在调试器或硬件模拟器中,enum可提供有用的显示参考信息。临时变量是全局定义的处理方式的例外。仅对于函数参数或自动变量,才使用enum类型进行定义。在这种情况下,int将是最有效的字长以及enum的标准行为。没有错误的可能,也无法进行超优化。