wcy
wcy

Reputation: 915

Is C variadic macro able to expand ##__VA_ARGS__ recursively?

variadic macro mentioned about VA_ARGS for gcc.

I did the following experiment.

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

And

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

So far so good, but

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

I must supply at least one argument, I solve the problem according to manual, use '##'.

#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))

So far so good, but

#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))

We can see the second EVAL is not expanded, but without '##', the second EVAL is expaned.

#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))

So here is the situation

  1. without ##, I have to supply at east one argument, but macro can be recursively expanded.
  2. with ##, zero argument is OK but macro cannot be evaluated recursively.

Can I have both problems solved at the same time?

Upvotes: 1

Views: 1009

Answers (1)

a427
a427

Reputation: 66

Can you please try this ?

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

It seems to work on my side because :

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

gives :

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))

Upvotes: 5

Related Questions