环境:
我在C99中定义了一个枚举:
enum MY_ENUM {TEST_ENUM_ITEM1, TEST_ENUM_ITEM2, TEST_ENUM_ITEM_MAX};
我确保编译时声明TEST_ENUM_ITEM_MAX
不超过UINT16_MAX
。我假设小端是字节顺序。
我有一个带有以下参数的序列化缓冲区函数:
PutIntoBuffer(uint8_t* src, uint32_t count);
我将保存值的变量序列化到缓冲区中。对于此任务,我访问变量,持有枚举,如下所示:
enum MY_ENUM testVar = TEST_ENUM_ITEM;
PutIntoBuffer((uint8_t*) &testVar, sizeof(uint16_t));
问题:以这种方式访问枚举(这是一个int)是否合法? C标准是否保证了预期的行为?
答案 0 :(得分:1)
它是合法的,因为“如果int是16位,它将起作用”。只要您使用像Binding
这样的字符类型,它也不会违反任何指针别名规则。 (反序列化是另一个故事。)
但是,代码不可移植。如果<DataGridTextColumn Header="ProductId1" Binding="{Binding Path=Result[1]}"
Visibility="{Binding Data.Columns[0].Visible, Source={StaticResource proxy}}"
Width="{Binding Data.Columns[0].Width, Source={StaticResource proxy}, Mode=TwoWay}" />
是32位,枚举常量也将变为32位,枚举变量本身也是如此。然后代码将依赖于endianess,你最终可能会阅读垃圾。根据UINT16_MAX检查TEST_ENUM_ITEM_MAX无法解决此问题。
序列化枚举的正确方法是使用预先生成的只读查找表,该表保证为8位,如下所示:
uint8_t
如果在维护期间更新枚举,则指定的初始化程序语法可提高数据的完整性。同样,静态断言将确保列表包含正确数量的项目。