simplecpp icon indicating copy to clipboard operation
simplecpp copied to clipboard

Failure to expand x-macro

Open mavik1 opened this issue 4 years ago • 2 comments

The gcc preprocessor doesn't match the cppcheck preprocessor output for the following:

#define IF_ELSE(condition) _IF_ ## condition
#define _IF_1(...) __VA_ARGS__ _IF_1_ELSE
#define _IF_0(...)             _IF_0_ELSE

#define _IF_1_ELSE(...)
#define _IF_0_ELSE(...) __VA_ARGS__

#define COLOR X(red, 1)

#define X(color, warm) IF_ELSE(warm)(color)()

COLOR
> cppcheck --version
Cppcheck 2.3
> cppcheck -E main.c











 red  _IF_1_ELSE  (  )

> gcc -E main.c
> gcc -E main.c
# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "main.c"
# 12 "main.c"
red

I haven't been able to come up with a work around for this one so far.

mavik1 avatar Jan 10 '21 22:01 mavik1

Without the x-macro it works fine:

#define IF_ELSE(condition) _IF_ ## condition
#define _IF_1(...) __VA_ARGS__ _IF_1_ELSE
#define _IF_0(...)             _IF_0_ELSE

#define _IF_1_ELSE(...)
#define _IF_0_ELSE(...) __VA_ARGS__

IF_ELSE(1)(red)()
> cppcheck -E main.c







red

mavik1 avatar Jan 10 '21 22:01 mavik1

I managed to work around the issue by forcing extra preprocessor passes with an EVAL4() macro

#define EVAL4(...) EVAL2(EVAL2(__VA_ARGS__))
#define EVAL2(...) EVAL1(EVAL1(__VA_ARGS__))
#define EVAL1(...) __VA_ARGS__

#define IF_ELSE(condition) _IF_ ## condition
#define _IF_1(...) __VA_ARGS__ _IF_1_ELSE
#define _IF_0(...)             _IF_0_ELSE

#define _IF_1_ELSE(...)
#define _IF_0_ELSE(...) __VA_ARGS__

#define COLOR X(red, 1)

#define X(color, warm) EVAL4(IF_ELSE(warm)(color)())

COLOR
> cppcheck -E main.c















 red

mavik1 avatar Oct 24 '21 08:10 mavik1