Home > Mobile >  C Macro Arguments including comma
C Macro Arguments including comma

Time:06-02

I would like to pass 2 arguments to a macro using another macro:

#define A_AND_B     5,1
#define ADD(a, b)   a   b

int add_them(void)
{
    int result = ADD(A_AND_B);
    return result ;
}

I would hope that expands to

int result = 5   1;

and I get 6. Instead I get

Error       'ADD' undeclared (first use in this function)   
Error       macro "ADD" requires 2 arguments, but only 1 given  

Is there a way around this?

CodePudding user response:

As is often the case, you need an extra level of (macro) indirection:

#define A_AND_B     5,1
#define ADD(...)    ADD_(__VA_ARGS__)
#define ADD_(a, b)   a   b

int add_them(void)
{
    int result = ADD(A_AND_B);
    return result ;
}

ADD is defined as variadic so that it will work as either ADD(A_AND_B) or ADD(A, B).

This works because __VA_ARGS__ in the replacement body of ADD is replaced with the actual arguments before the replacement body is scanned for macros.

CodePudding user response:

Per C 2018 6.10.3.1, a compiler first identifies the arguments for a function-like macro and then performs macro replacement on the arguments, followed by macro replacement for the function-like macro. This means that, in ADD(A_AND_B), the argument is identified as A_AND_B before it is replaced with 5,1. As the macro invocation has only this single argument and the macro is defined to have two parameters, an error is diagnosed.

Given your definition of ADD, there is no way to change this behavior in a compiler that conforms to the C standard.

You can instead use another macro to expand the arguments and apply the desired macro:

#define Apply(Macro, Arguments) Macro(Arguments)

then int result = Apply(ADD, A_AND_B); will work. That will identify ADD and A_AND_B as arguments to Apply. Then it will expand those, producing an unchanged ADD and 5,1. Then the macro replacement for Apply produces ADD(5,1). Then this is again processed for macro replacement, which replaces ADD(5,1) in the ordinary way.

Note that good practice is usually to define ADD as #define ADD(a, b) ((a) (b)) to avoid unexpected interactions with other operators neighboring the use of the macro.

  • Related