我想使用可变参数宏,但是它似乎仅设计为专门处理第一个参数。我希望前两个参数被命名,其余的不被命名,像这样:
#define FOO(AA,BB,...) AA->BB(AA,##...)
FOO(mystruct,funcname,123)
但是,这不适用于LLVM。我是在做错什么,还是可变参数宏的工作方式受到限制?
更新
正确的答案是,使用## VA_ARGS 代替## ...
有些网页声称“ ...”有效,但至少对于MacOS llvm无效。
答案 0 :(得分:1)
宏参数不会在宏扩展中使用...
进行扩展-怎么可能,因为那样的话,您将无法在扩展中使用使用省略号的宏。相反,它将作为特殊参数__VA_ARGS__
可用。
有了这个,下面的程序
#define FOO(AA,BB,...) AA->BB(AA, __VA_ARGS__)
FOO(mystruct,funcname,123)
FOO(mystruct,funcname,123,456)
##
是粘贴令牌的运算符。它将由2个部分组成一个预处理令牌。 , ## ...
尝试制作预处理令牌,...
。这不是有效的C令牌,这就是Clang会报告的原因
<source>:3:1: error: pasting formed ',...', an invalid preprocessing token
答案 1 :(得分:1)
...
宏参数通过__VA_ARGS__
粘贴到宏体中。
问题是如何允许它为空。
如果为空,则通常需要先擦除逗号,然后再
您可以使用GNU ##__VA_ARGS__
扩展名来实现。
#define FOO(AA,BB,...) AA->BB(AA,##__VA_ARGS__) /*GNU extension*/
FOO(mystruct,funcname) //warning with -pedantic
FOO(mystruct,funcname,123)
但是,如果使用-pedantic
进行编译,以上内容将触发警告。
如果您希望宏在-pedantic
时不加警告地可用,则可以通过交换宏定义中的前两个参数来实现。
#define FIRST(...) FIRST_(__VA_ARGS__,)
#define FIRST_(X,...) X
#define BAR_(CallExpr,...) CallExpr(__VA_ARGS__)
#define BAR(BB,/*AA,*/...) BAR_(FIRST(__VA_ARGS__)->BB,__VA_ARGS__)
BAR(funcname,mystruct) //no warning
BAR(funcname,mystruct,123)