#define call_foo(...) \
do { \
int first; \
int second; \
int third; \
(__VA_ARGS__); \
foo(first, second, third); \
} while (0)
....
int main(void) {
call_foo(first=9, third=5, second=3);
}
Getting return values in a non-clunky manner is more difficult.
This would allow you to do very silly things (which I hate) such as specify default values for your arguments:
#define call_foo(...) \
do { \
int first = default_first; \
int second; \
int third; \
(__VA_ARGS__); \
foo(first, second, third); \
} while (0)
This will fail if you do:
int first = 9;
call_foo(first=first, third=5, second=3);
because in the macro expansion the first=first
will mean initialize the local first
with itself. I thought about trying to get around this with preprocessor concatenation, but that gets more complicated. You would have to list the same number of macro parameters as function parameters.
#define call_foo(x, y , z) \
do { \
int call_foo_first; \
int call_foo_second; \
int call_foo_third; \
call_foo_##x; \
call_foo_##y; \
call_foo_##z; \
foo(call_foo_first, call_foo_second, call_foo_third); \
} while (0)
The call_foo_##x;
line would turn into call_foo_first=first;
if called in the previous example, so each symbol has it's own unique name.
This makes the default argument trick more awkward because you'd have to specify something to fill that spot in the macro argument list.
If the macro were defined with a default argument for first
then:
call_foo(first, third=7, second=8);
This forces you to list all parameters (or at least something that results in legal C -- you could have listed second twice, but you could have done that anyway) in order use this macro.
I think you should be able to extend the last version of this for variable argument listed macros/functions, but the optional parameters would still have to be passed at the end of the list and you would have to use up all of the mandatory spots before you got to the optional arguments.