C macro expansion not recursive as expected

Viewed 125
#define EVAL1(...) __VA_ARGS__
#define RECURSE() I am recursive, look: _RECURSE()()
#define _RECURSE() RECURSE

I expected:
EVAL1(RECURSE())
=> EVAL1(I am recursive, look: _RECURSE()())
=> EVAL1(I am recursive, look: RECURSE())
=> I am recursive, look: RECURSE()
=> I am recursive, look:I am recursive, look: _RECURSE()()

what I got:
EVAL1(RECURSE())
=> I am recursive, look: RECURSE()

Why is RECURSE() not expanded second time when it is passed as an argument to EVAL1?

Another way to achieve what I want is this:

#define EVAL1(...) __VA_ARGS__
#define EMPTY()
#define DEFER1(m) m EMPTY()
#define RECURSE() I am recursive, look: DEFER1(_RECURSE)()()
#define _RECURSE() RECURSE

EVAL1(RECURSE())
=> I am recursive, look: I am recursive, look: _RECURSE ()()

But I am not sure why this works.

1 Answers

The C preprocessor does not allow recursion. More precisely, while the preprocessor is expanding macros, it remembers which macros it's expanding. If it finds one of the macros that are currently being expanded, it leaves it unchanged.

In your example, the evaluation chain is:

  • EVAL1(RECURSE())
  • expanding EVAL1: RECURSE()
  • expanding EVAL1, RECURSE: I am recursive, look: _RECURSE()()
  • expanding EVAL1, _RECURSE, RECURSE: I am recursive, look: RECURSE()
  • nothing left to expand, done.

Forbidding recursion lets you wrap a function with a macro that has the same name. For example:

#define foo(x, y) (printf("DEBUG: foo was called in %s at line %d\n", __FILE__, __LINE__), foo(x, y))

Forbidding recursion also guarantees that the compilation will terminate. (This is actually not true: you can get infinite recursion through #include directives. But it takes more work than a simple recursive #define. Also termination doesn't necessarily mean quick termination: it's possible to build preprocessor expansions that only terminate after a very long time.)

Related