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

Jax*_*xWR 6 c c-preprocessor

我想做这样的事情:

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

NEED3ARGS( MULTIARG() )
Run Code Online (Sandbox Code Playgroud)

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

( "[" "ARG1" " + " "ARG2" " + " "ARG3" "]" )
Run Code Online (Sandbox Code Playgroud)

但相反,我有:

$ cpp multiarg.c 
# 1 "multiarg.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "multiarg.c"

multiarg.c:4:23: error: macro "NEED3ARGS" requires 3 arguments, but only 1 given
NEED3ARGS
Run Code Online (Sandbox Code Playgroud)

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

谢谢!

Jam*_*lis 12

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

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

INVOKE_NEED3ARGS( MULTIARG() )
Run Code Online (Sandbox Code Playgroud)

(严格要求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() )
Run Code Online (Sandbox Code Playgroud)

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

INVOKE_NEED3ARGS宏可确保其参数完全评估之前NEED3ARGS调用.的__VA_ARGS__是由宏替换参数取代的INVOKE_NEED3ARGS,这是ARG1, ARG2, ARG3,则NEED3ARGS调用与那些参数.


Dan*_*her 6

是,

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

NEED1ARG( MULTIARG() )
Run Code Online (Sandbox Code Playgroud)

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