I have a system with many parameter sets "macroized" (macros of the form "#define name value,value,value). I would like to pass these to a macro, but when I do I get an error.
example:
void fn(int a, int b, int c){ return; }
#define MACRO_1(a, b, c) fn(a, b, c)
#define MACRO(...) MACRO_1(__VA_ARGS__)
#define PARAM1 1
#define PARAM2 2, 2
#define PARAM3 3, 3, 3
int main(int argc, char * argv[]){
MACRO(0,0,0);
MACRO(PARAM1,1, 1);
MACRO(PARAM2,2);
MACRO(PARAM3);
return 0;
}
in Visual C I get:
1>c:\main.c(10): warning C4003: not enough actual parameters for macro 'MACRO_1'
1>c:\main.c(10): error C2059: syntax error : ','
1>c:\main.c(11): warning C4003: not enough actual parameters for macro 'MACRO_1'
1>c:\main.c(11): error C2059: syntax error : ','
1>c:\main.c(12): warning C4003: not enough actual parameters for macro 'MACRO_1'
1>c:\main.c(12): error C2059: syntax error : ','
1>c:\main.c(13): warning C4003: not enough actual parameters for macro 'MACRO_1'
1>c:\main.c(13): error C2059: syntax error : ','
This is a bug in the Visual C++ compiler. The compiler does not correctly expand the variadic argument pack when __VA_ARGS__
appears as an argument to another macro.
The workaround is to use an additional layer of indirection to force the variadic argument pack to be expanded before MACRO_1
is invoked:
#define MACRO_1(a, b, c) fn(a, b, c)
#define MACRO_1_(args_list) MACRO_1 args_list
#define MACRO(...) MACRO_1_((__VA_ARGS__))
There is a Microsoft Connect bug for this issue: "Variadic Macro Replacement." If this issue is important to you, please upvote that bug report.
MACRO
takes any number of arguments (...), and doesn't use#
or##
on them, so any macros in the arguments (PARAM1
,PARAM2
, etc) should be expanded before theMACRO_1
in the body gets scanned or expanded - Chris Dodd 2012-04-03 22:28