C可变参数宏是否能够递归扩展##__VA_ARGS__?
Is C variadic macro able to expand ##__VA_ARGS__ recursively?
variadic macro 提到 VA_ARGS 用于 gcc。
我做了以下实验。
#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))
情况是这样
- 没有
##
,我必须至少提供一个参数,但是宏可以递归展开。
- with
##
,零参数可以,但不能递归计算宏。
我可以同时解决这两个问题吗?
你能试试这个吗?
#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))
variadic macro 提到 VA_ARGS 用于 gcc。
我做了以下实验。
#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))
情况是这样
- 没有
##
,我必须至少提供一个参数,但是宏可以递归展开。 - with
##
,零参数可以,但不能递归计算宏。
我可以同时解决这两个问题吗?
你能试试这个吗?
#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))