为什么这个嵌套的宏替换失败了?

Ant*_*nio 9 c macros initialization c-preprocessor

我正在尝试应用X宏概念,以便有可能将所有struct成员初始化为自定义默认(无效)值.我写下面的代码:

#define LIST_OF_STRUCT_MEMBERS_foo \
    X(a) \
    X(b) \
    X(c)

#define X(name) int name;
struct foo {
     LIST_OF_STRUCT_MEMBERS_foo
};
#undef X


#define X(name) -1,
static inline void foo_invalidate(struct foo* in) {
     *in = (struct foo){
     LIST_OF_STRUCT_MEMBERS_foo
     };
}
#undef X

#define X(name) -1,
#define foo_DEFAULT_VALUE  { LIST_OF_STRUCT_MEMBERS_foo }
#undef X

static struct foo test = foo_DEFAULT_VALUE;
Run Code Online (Sandbox Code Playgroud)

但是,当我运行预处理器时,定义foo_DEFAULT_VALUE无法替换X(name)调用-1,

预处理器输出:

struct foo {
     int a; int b; int c;
};

static inline void foo_invalidate(struct foo* in) {
     *in = (struct foo){
     -1, -1, -1, /*Here the substitution worked nicely*/
     };
}

static struct foo test = { X(a) X(b) X(c) }; /*Why this substitution failed?*/
Run Code Online (Sandbox Code Playgroud)

我以为C-macros可以引用其他宏.你知道为什么替换失败了吗?有没有解决方法?

我可以忍受foo_invalidate,但我不愿意在初始化时直接使用一个值而放弃一步.

Eug*_*Sh. 9

让我们假装我们是预处理器并遇到这条线:

static struct foo test = foo_DEFAULT_VALUE;
Run Code Online (Sandbox Code Playgroud)

通过1:

static struct foo test = { LIST_OF_STRUCT_MEMBERS_foo };
Run Code Online (Sandbox Code Playgroud)

通过2:

static struct foo test = { X(a) X(b) X(c) };
Run Code Online (Sandbox Code Playgroud)

传递3:没有什么可以扩展,因为X这行未定义.


一种解决方法可能是定义一个const变量(可能但不一定static)用作默认值:

#define X(name) -1,
static const struct foo foo_DEFAULT_VALUE = { LIST_OF_STRUCT_MEMBERS_foo };
#undef X
Run Code Online (Sandbox Code Playgroud)

哪个产生:

static const struct foo foo_DEFAULT_VALUE = { -1, -1, -1, };
Run Code Online (Sandbox Code Playgroud)

  • 而不是将`foo_DEFAULT_VALUE`定义为扩展为初始化器的宏,您可以使用*initializer将其声明为`const struct foo`*. (2认同)