The ## operator performs exact token substitution, so in this case it tries to send the token "CALL(func1, false)" as the last argument to the func1 C function.
The problem is that CALL is a macro, and you cannot insert macro variables into the list ##__VA_ARGS__ .
The reason it works when an internal macro is passed as a named argument is because the preprocessor will parse the named arguments for the internal macros, but not ##__VA_ARGS__ , where there is a simple token replacement.
One way to solve this problem is to assign the result of the internal CALL variable to the placeholder variable, and then pass it along with the macro.
int main() { CALL(func2, CALL(func1, false), false); bool result = CALL(func1, false); CALL(func2, false, result); }
Another way to solve this problem is to simply use __VA_ARGS__ as the only argument to the func function, and this will allow you to pass nested macros, for example:
#define CALL(func, ...) func(__VA_ARGS__) int main() { CALL(func2, false, CALL(func2, false, false)); }
Analyze your dilemma in more detail:
CALL(func2, false, CALL(func1, false))
In this particular macro call, CALL now ("func2", "tmp", CALL(func1, false)) so he tries to call func1 , passing in tmp and, well, CALL(func1, false) .
Here the line is output between the preprocessor and the actual C compiler.
The preprocessor, after it starts performing the substitution, performed the parsing, so the compiler gets CALL(func1, false) as the actual C function, not a macro, because the compiler does not know about macros, but only the preprocessor.