【发布时间】:2017-08-19 18:07:11
【问题描述】:
[注意:这与 Specifying size of enum type in C 和 What is the size of an enum in C? 有关,但在这些问题中,问题是如何最小化封闭结构的大小。在这里,我们要指定结构的各个成员的大小,但仍然获得 typedef 枚举的文档优势]
我正在实现串行通信协议的客户端。我想使用 C 结构来捕获串行数据包的格式,我想使用 C 枚举来定义数据包中各个插槽的合法值。
我没有看到两种方法都可以,但由于我使用的是 GCC,所以可能有可能。
作为问题的假设示例,假设我收到的数据包如下所示:
typedef struct {
uint16_t appliance_type;
uint8_t voltage;
uint16_t crc;
} __attribute__((__packed__)) appliance_t;
这很清楚,我很确定我会得到一个 5 个字节长的结构。但它没有捕捉到appliance_type 和voltage 只能采用某些值的事实。
我更喜欢这样的……
typedef enum {
kRefrigerator = 600,
kToaster = 700,
kBlender = 800
} appliance_type_t;
typedef enum {
k120vac = 0,
k240vac = 1,
k12vdc = 2
} voltage_t;
typedef struct {
appliance_type_t appliance_type;
voltage_t voltage;
uint16_t crc;
} appliance_t;
...但据我所知,无法指定 Appliance_type_t 为 16 位,而 voltage_t 为 8 位。
有没有办法让我的蛋糕也吃掉?
更新:
我需要明确指出,我不希望编译器将枚举值强制为各个字段的设置器!相反,我发现 typedef 的枚举对于代码的维护者来说是一个有用的构造,因为它明确了预期的值是什么。
注意:当我对此进行研究时,我注意到 GCC 枚举接受 __attribute__ 规范,但我不确定这是否有帮助。
【问题讨论】:
-
你应该摆脱打包结构并序列化/反序列化你的数据包......
-
枚举常量的类型是
int。您可以将任意整数分配给枚举变量。它没有提供您认为的类型安全。 -
在 C++ 中可以设置 type of enum members 但我不知道 C 中是否有类似的东西
-
@Lundin - 我的书呆子想争辩说,这是指针类型提供的类型安全,而不是枚举类型的常量:)
-
@StoryTeller 这启发了我想出一个小技巧来解决这个问题,在这里:stackoverflow.com/questions/43043246/…