在C语言中将一个有条件编译的枚举类型转换成字符串

3
我们的系统有很多枚举,表示事件、错误等等。
我正在尝试构建基础设施,使我们能够将每个接收到的事件或错误消息记录为字符串(而不是普通整数),而无需构建和维护每个枚举的两个列表。
我发现X宏技术非常适合我的需求。因此,不需要这样做:
typedef enum
{
   valA,
   valB,
   valC
} some_enum;

const char* some_enum_strings[] =
{                                                                                       
    "valA",
    "valB",
    "valC"
};

我正在操作以下内容:
#define DEF_STRINGIFY(_x_) #_x_,
#define DEF_ENUM(_x_) _x_,

#define ENUM_NAME(_x_) \
    _x_(valA) \
    _x_(valB) \
    _x_(valC) 

typedef enum
{
    SOME_ENUM(DEF_ENUM)
} some_enum;

const char* some_enum_strings[] =
{                                                                                       
    SOME_ENUM(DEF_STRINGIFY)
};

虽然这样做很好,但问题是我们的一些枚举类型非常大,包含数百个值,并且充满了条件编译,看起来更像这样:

typedef enum
{
   valA,
#if defined (SYS_A)
   valB,
#endif
   valC,
   valD,
#if defined (SYS_B) || defined (SYS_D)
   valE,
#else
   valF,
#endif
   valG
/* etc. */
} some_enum;

事实证明,C不允许在宏内使用条件编译。Eclipse显示“宏中的宏拼接无效”,并且当我尝试构建代码时,由于“错误:'#'后面没有宏参数”而失败(行号与宏内第一个#if语句相匹配)。
所以现在我非常困惑,希望得到任何建议。
如果要提出解决方案,请注意以下内容:
- 我不能每个枚举值都有一个列表。 - 这个解决方案需要应用到大量的枚举类型。(也就是说我不能将每个枚举类型放在它自己的.h文件里)
谢谢。

我的建议是:选择任何一个有源代码可用的简单C编译器 - tcc(Fabrice Bellard的),sdc(Small Device C Compiler)等,只要它足够完整以正确解析您的代码即可。唯一重要的是,您可以快速定位到构建枚举的源代码部分。然后将其修改为生成文本输出 - 拥有大型“select”和每个值的“case”的函数,并返回字符串。这几乎是唯一不会完全笨拙且仍然有效的解决方案。从编译器中删除codegen等内容以使其更加精简。 - Kuba hasn't forgotten Monica
1个回答

1

P99P99_DECLARE_ENUM等函数,让您可以很好地处理enum。您可以获得返回名称等字符串的函数。这应该能够抵御条件编译的影响。唯一的限制是一个enum类型中可以拥有的值的总数,但可能会有方法来扩展此限制。


谢谢。我还不确定如何使用它,但它听起来像是一个好的解决方案。 - IdanDe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接