递归 C 宏未扩展

Recursive C macro not expanded

我正在研究递归宏。不过貌似不是递归展开的。这是一个最小的工作示例来说明我的意思:

// ignore input, do nothing
#define ignore(...)
// choose between 6 names, depending on arity
#define choose(_1,_2,_3,_4,_5,_6,NAME,...) NAME
// if more than one parameter is given to this macro, then execute f, otherwise ignore
#define ifMore(f,...) choose(__VA_ARGS__,f,f,f,f,f,ignore)(__VA_ARGS__)
// call recursively if there are more parameters
#define recursive(first,args...) first:ifMore(recursive,args)

recursive(a,b,c,d)
// should print: a:b:c:d
// prints: a:recursive(b,c,d)

recursive 宏应该递归地扩展自身并始终连接结果,用冒号分隔。但是,它不起作用。递归宏已正确生成(如结果 a:recursive(b,c,d) 所示,其中再次包含对宏的格式正确的调用),但生成的递归调用未扩展。

为什么会这样,我怎样才能得到我想要的行为?

您得不到想要的行为。 C 预处理器在设计上并不完整。

您可以使用多个宏来获得多个替换,但您无法通过任意数量的替换实现真正的递归。

编译器预处理器不会重新展开您定义的宏。也就是说,它会盲目地将宏语句中找到的任何字符串替换为它在定义中找到的字符串。例如,Can we have recursive macros? or Macro recursive expansion to a sequence and C preprocessor, recursive macros

也就是说,recursive(a,b,c,d) 将扩展为 a:recursive(b,c,d),然后预处理器将继续执行基本代码中的下一行。它不会循环尝试继续扩展字符串(请参阅我引用的链接)。

正如其他人所提到的,纯递归对于 C 宏是不可能的。但是,可以模拟类似递归的效果。

Boost 预处理器工具在 C 和 C++ 上都做得很好,并且是一个独立的库:

http://www.boost.org/doc/libs/1_60_0/libs/preprocessor/doc/index.html