将枚举字符串(不是值)传递给宏

Passing an enum string (not value) to a macro

本文关键字:枚举 字符串      更新时间:2023-10-16

我有这个查询其中我有一个枚举和一个结构体,像这样,

enum fields {
   field_1,
   field_2
};
struct my_struct {
    int field_1;
    int field_2;
};

我的具体需要是,给定具有结构成员(field_1, field_2等)名称的enum,我应该能够生成一个宏,该宏可以将结构成员设置为给定值。

#define my_macro (__a, __field) 
__a.__field = 1;
那么有没有一种方法可以像这样调用my_macro:
struct my_struct b;
/* extract members of enum as string literals  */
my_macro(b, /*field name from the enum */);

其他几个帖子详细使用boost宏帮助我提取枚举成员作为字符串(如何将枚举类型变量转换为字符串?)。问题是如何以适当的方式将其传递给宏。

应该是这样的。宏在编译之前被处理,而代码仍然是代码,它们导致代码生成。

#define my_macro(__a, __field) __a.__field = 1;将导致任何条目(如my_macro(x, y))在交给编译器之前被转换为x.y = 1;

如果您执行类似my_macro(1+1, "test")的操作,它将生成代码1+1."test" = 1;并将创建编译错误。这就是简单的宏。

这就是为什么宏参数通常被()包围,以确保它会按照预期的方式工作,如果你不这样做,像这样的事情可能会发生:

#define div_by_100(a) a / 100
printf("%dn", div_by_100(1000)); // will print 10
printf("%dn", div_by_100(500 + 500)); // will print 505

这是因为操作顺序是在编译时解析完宏之后才解析的。

请注意,因为宏是在编译之前解析的,所以它们不是运行时解决方案。如果这个enum值在代码中没有显式显示,那么宏将完全无法帮助您。您必须编写一个路由函数,该函数将根据给定的enum值为该类/结构的每个成员赋值。例子:

void route(struct farm* s, enum animals e)
{
    switch (e)
    {
        case cow:
            s->cow = 1;
            break;
        case duck:
            s->duck = 1;
            break;
        case horse:
            s->horse = 1;
            break;
        case goat:
            s->goat = 1;
            break;
    }
}

这取决于将enum转换为string的机制。只要该机制仍然是一个被预处理器取代的宏,您的宏就应该工作。这就是问题所在。否则你的宏应该能正常工作。