简体   繁体   中英

How to fix the macro expansion problem in C

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM