gpt4 book ai didi

c - 对 C 枚举的部分字节访问

转载 作者:行者123 更新时间:2023-11-30 14:54:23 25 4
gpt4 key购买 nike

设置:

  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));

问题:以这种方式访问​​枚举(它是一个 int)是否合法? C 标准能否保证预期的行为?

最佳答案

它是合法的,就像“如果 int 是 16 位它将工作”一样。只要您使用像 uint8_t 这样的字符类型,它也不违反任何指针别名规则。 (反序列化是另一个故事。)

但是,该代码不可移植。如果 int 是 32 位,则枚举常量也将变为 32 位,枚举变量本身也可能变为 32 位。然后代码将变得依赖于字节顺序,您可能最终会读到垃圾。检查 TEST_ENUM_ITEM_MAX 与 UINT16_MAX 并不能解决这个问题。

序列化枚举的正确方法是使用预先生成的只读查找表,该表保证为 8 位,如下所示:

#include <stdint.h>

enum MY_ENUM {TEST_ENUM_ITEM1, TEST_ENUM_ITEM2, TEST_ENUM_ITEM_MAX};

static const uint8_t MY_ENUM8 [] =
{
[TEST_ENUM_ITEM1] = TEST_ENUM_ITEM1,
[TEST_ENUM_ITEM2] = TEST_ENUM_ITEM2,
};

int main (void)
{
_Static_assert(sizeof(MY_ENUM8)==TEST_ENUM_ITEM_MAX, "Something went wrong");
}

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

关于c - 对 C 枚举的部分字节访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46787017/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com