Home > Enterprise >  How to fix the macro expansion problem in C
How to fix the macro expansion problem in C

Time:01-19

How to fix the macro expansion issue below ?

#define GET_VAL                        3,2
#define ADD_VAL(val0, val1)            ((val0)   (val1))

void foo()
{
    int res = ADD_VAL(GET_VAL);
}

The macro is getting expanded as below and resulting in an error. I am using MSVC 2019

res = 3,2   ;

I even tried using a helper macro as below, but still getting the same error.

#define GET_VAL                  3,2
#define ADD_VAL1(val0, val1)     (val0   val1)
#define ADD_VAL(val)             ADD_VAL1(val)

Expecting expansion: ADD_VAL(GET_VAL); --> ADD_VAL(3, 2); --> 3 2

CodePudding user response:

C preprocessor can be abused in horrible ways

#define GET_VAL                3,2
// #define ADD_VAL(val0, val1)    ((val0)   (val1))
#define ADD_VAL(val)       ((int [2]){val}[0]   (int [2]){val}[1])

int main() {
  printf("%d\n",ADD_VAL(GET_VAL));
}

Output

5

CodePudding user response:

By default msvc doesn't use a standard confirming preprocessor implementation, make sure to enable it with /Zc:preprocessor

Macros fully expand their arguments in isolation before pasting them into the replacement text, but the resulting tokens aren't separated into a new argument list. They way to fix your behavior is to create an intermediate macro that expands the arguments, and passes the expanded arguments to your macro:

#define GET_VAL 1,2
#define ADD_VAL(...) ADD_VAL_(__VA_ARGS__)
#define ADD_VAL_(a,b) ((a) (b))
ADD_VAL(GET_VAL) // should work now

Another option is to write a fx macro that evaluates arguments and applies a function to them:

#define FX(f,...) f(__VA_ARGS__)
#define ADD_VAL(a,b) ((a) (b))
FX(ADD_VAL,GET_VAL) // should work now
  • Related