1

Why does the following minimal example not work?

static inline int test_1(int x) { return x; }
#define TEST(a, ...) test_##a(__VA_ARGS__)
#define ONE 1
void temp() {
    TEST(1, 5); // OK
    TEST(ONE, 5); // error: use of undeclared identifier 'test_ONE'
}

From my understanding, macros inside macros should work as long as they are not recursive.

unDeadHerbs
  • 1,306
  • 1
  • 11
  • 19
wondering
  • 363
  • 5
  • 14

1 Answers1

1

If you use the -E option you can see what your code looks like after the pre-processor stage.

Macros are expanded in multiple passes and have their own order of precedence.

In this case TEST(ONE,5) is expanding directly to test_ONE(5).

If you add a single layer (or more) of indirection you can cause ONE to expand before the ## operator is seen.

#define TEST_I(a,...)test_##a(__VA_ARGS__)
#define TEST(a, ...) TEST_I(a,__VA_ARGS__)

As on the first pass TEST(ONE,5) is expanded into TEST_I(ONE,5) and then TEST_I(1,5), and on second pass this becomes test_1(5).

The TEST_I isn't expanded on the first pass though because it is generated by the expansion of TEST whereas the ONE was already present.

unDeadHerbs
  • 1,306
  • 1
  • 11
  • 19