【问题标题】:Is C variadic macro able to expand ##__VA_ARGS__ recursively?C 可变参数宏是否能够递归扩展##__VA_ARGS__?
【发布时间】:2015-05-28 07:13:35
【问题描述】:

variadic macro 提到了 gcc 的 VA_ARGS

我做了以下实验。

#define EVAL(f,...) eval(f,build_args(args,__VA_ARGS__ , args_end))

还有

EVAL(f,a) // => eval(f,build_args(args,a, args_end))
EVAL(f,a,b) // => eval(f,build_args(args,a,b, args_end))

到目前为止还不错,但是

EVAL(f) // => eval(f,build_args(args, , args_end))

我必须提供至少一个参数,我按照手册解决问题,使用'##'。

#define EVAL(f,...) eval(f,build_args(args,##__VA_ARGS__ , args_end))
EVAL(f,a) // => eval(f,build_args(args,a, args_end))
EVAL(f,a,b) // => eval(f,build_args(args,a,b, args_end))
EVAL(f) // => eval(f,build_args(args, args_end))

到目前为止还不错,但是

#define EVAL(f,...) eval(f,build_args(args,##__VA_ARGS__ , args_end))
EVAL(f,EVAL(g,a)) // => eval(f,build_args(args,EVAL(g,a) , args_end))

我们可以看到第二个EVAL没有展开,但是没有'##',第二个EVAL被展开了。

#define EVAL(f,...) eval(f,build_args(args,##__VA_ARGS__ , args_end))
EVAL(f,EVAL(g,a)) // => eval(f,build_args(args,
                  //          eval(g,build_args(args,a , args_end), 
                  //                 args_end))

情况就是这样

  1. 没有##,我必须在east 提供一个参数,但宏可以递归扩展。
  2. 使用##,零参数是可以的,但不能递归地评估宏。

我可以同时解决这两个问题吗?

【问题讨论】:

  • 它是否适用于间接宏?

标签: c gcc macros variadic


【解决方案1】:

你能试试这个吗?

#define _build_args(args,f,...) eval(f,build_args(args,__VA_ARGS__))
#define EVAL(f...) _build_args(args,f,args_end)

这似乎对我有用,因为:

EVAL(f,a)
EVAL(f,a,b)
EVAL(f)
EVAL(f,EVAL(g,a))

给:

eval(f,build_args(args,a,args_end))
eval(f,build_args(args,a,b,args_end))
eval(f,build_args(args,args_end))
eval(f,build_args(args,eval(g,build_args(args,a,args_end)),args_end))

【讨论】:

  • 是的,它也适用于我。谢谢!你的回答被接受了。
猜你喜欢
  • 1970-01-01
  • 2012-08-01
  • 2014-09-01
  • 2016-07-28
  • 2021-05-23
  • 1970-01-01
  • 2014-03-03
  • 1970-01-01
相关资源
最近更新 更多