对C enum的部分字节访问

时间:2017-10-17 09:35:48

标签: c enums

环境:

  1. 我在C99中定义了一个枚举:

    enum MY_ENUM {TEST_ENUM_ITEM1, TEST_ENUM_ITEM2, TEST_ENUM_ITEM_MAX};
    
  2. 我确保编译时声明TEST_ENUM_ITEM_MAX不超过UINT16_MAX。我假设小端是字节顺序。

  3. 我有一个带有以下参数的序列化缓冲区函数:

    PutIntoBuffer(uint8_t* src, uint32_t count);
    
  4. 我将保存值的变量序列化到缓冲区中。对于此任务,我访问变量,持有枚举,如下所示:

    enum MY_ENUM testVar = TEST_ENUM_ITEM;
    
    PutIntoBuffer((uint8_t*) &testVar, sizeof(uint16_t));
    
  5. 问题:以这种方式访问​​枚举(这是一个int)是否合法? C标准是否保证了预期的行为?

1 个答案:

答案 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

如果在维护期间更新枚举,则指定的初始化程序语法可提高数据的完整性。同样,静态断言将确保列表包含正确数量的项目。