宏可以评估多个参数到另一个吗?

我想做这样的事情:

#define NEED3ARGS(a1,a2,a3) ( "[" #a1 " + " #a2 " + " #a3 "]" ) #define MULTIARG() ARG1, ARG2, ARG3 NEED3ARGS( MULTIARG() ) 

我希望它能输出如下内容:

 ( "[" "ARG1" " + " "ARG2" " + " "ARG3" "]" ) 

但相反,我有:

 $ cpp multiarg.c # 1 "multiarg.c" # 1 "" # 1 "" # 1 "multiarg.c" multiarg.c:4:23: error: macro "NEED3ARGS" requires 3 arguments, but only 1 given NEED3ARGS 

有没有办法用ANSI-C / GNU GCC和C预处理器做我想做的事情?

谢谢!

你需要一些间接的东西。 使用C99:

 #define NEED3ARGS(a1,a2,a3) ( "[" #a1 " + " #a2 " + " #a3 "]" ) #define INVOKE_NEED3ARGS(...) NEED3ARGS(__VA_ARGS__) #define MULTIARG() ARG1, ARG2, ARG3 INVOKE_NEED3ARGS( MULTIARG() ) 

(严格要求C99;您可以使用固定的宏替换可变参数宏。)

如果需要使用Visual C ++编译源代码,则需要更多间接(因为编译器错误 ):

 #define NEED3ARGS(a1,a2,a3) ( "[" #a1 " + " #a2 " + " #a3 "]" ) #define INVOKE_NEED3ARGS_(...) NEED3ARGS __VA_ARGS__ #define INVOKE_NEED3ARGS(...) INVOKE_NEED3ARGS_((__VA_ARGS__)) #define MULTIARG() ARG1, ARG2, ARG3 INVOKE_NEED3ARGS( MULTIARG() ) 

至于为何需要间接寻址:宏参数在被替换到替换列表之前不会被评估和宏替换。 因此,当您尝试NEED3ARGS(MULTIARG()) ,直到宏调用开始后才会对MULTIARG()进行求值,因此将其视为单个参数。

INVOKE_NEED3ARGS宏确保在调用NEED3ARGS之前完全评估其参数。 __VA_ARGS____VA_ARGS__的宏替换参数INVOKE_NEED3ARGS ,后者是ARG1, ARG2, ARG3 ,然后用这些参数调用NEED3ARGS

是,

 #define NEED3ARGS(a1,a2,a3) ( "[" #a1 " + " #a2 " + " #a3 "]" ) #define MULTIARG() ARG1, ARG2, ARG3 #define NEED1ARG(ARG) NEED3ARGS(ARG) NEED1ARG( MULTIARG() ) 

您需要将其包装在另一个宏调用中,以便在调用NEED3ARGS之前扩展参数。

添加到James McNellis的答案中,如果你需要将这个技巧应用于许多类似函数的宏(flm),你可以定义一个“调用”宏来为你做这个技巧。 这是一个完整的工作示例:

 #include int f(int x,int y) { return x + y; } #define g(x,y) x+y #define XY 1,2 #define _g(arg) g(arg) #define invoke(flm,...) flm(__VA_ARGS__) int main(int argc, char ** argv) { printf("%d\n",f(XY)); // functions are easy printf("%d\n",_g(XY)); // Jam,es' way printf("%d\n",invoke(g,XY)); // with generic invoke flm return 0; }