Может ли макрос C variadic рекурсивно расширяться ##__VA_ARGS__?

макрос variadic, упомянутый о 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))

Итак, вот ситуация

  1. без ##Я должен предоставить на востоке один аргумент, но макрос может быть рекурсивно расширен.
  2. с ##нулевой аргумент в порядке, но макрос не может быть оценен рекурсивно.

Могу ли я решить обе проблемы одновременно?

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))
Другие вопросы по тегам