2

I am working on a recursive macro. However, it seems that it is not expanded recursively. Here is a minimal working example to show what I mean:

// ignore input, do nothing
#define ignore(...)
// choose between 6 names, depending on arity
#define choose(_1,_2,_3,_4,_5,_6,NAME,...) NAME
// if more than one parameter is given to this macro, then execute f, otherwise ignore
#define ifMore(f,...) choose(__VA_ARGS__,f,f,f,f,f,ignore)(__VA_ARGS__)
// call recursively if there are more parameters
#define recursive(first,args...) first:ifMore(recursive,args)

recursive(a,b,c,d)
// should print: a:b:c:d
// prints: a:recursive(b,c,d)

The recursive macro should expand itself recursively and always concatenate the result, separated with a colon. However, it doesn't work. The recursive macro is generated correctly (as can be seen on the result a:recursive(b,c,d) which includes a well-formed call to the macro again), but the generated recursive call ist not exanded.

Why is this the case and how can I get the behaviour I want?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
gexicide
  • 38,535
  • 21
  • 92
  • 152
  • 1
    'I am working on a recursive macro' - well, it's difficult to know what to say to that:( Non-recursive macros are a PITA. – Martin James Apr 07 '16 at 16:02

3 Answers3

4

You can't get the behaviour you want. The C preprocessor is, by design, not turing complete.

You can use multiple macros to get multiple replacements, but you will not achieve true recursion with an arbitrary number of replacements.

Nils_M
  • 1,062
  • 10
  • 24
3

As others have mentioned, pure recursion is impossible with C macros. It is, however, possible to simulate recursion-like effects.

The Boost Pre-Processor tools do this well for both C and C++ and are a stand-alone library:

http://www.boost.org/doc/libs/1_60_0/libs/preprocessor/doc/index.html

Charles Ofria
  • 1,936
  • 12
  • 24
1

The compiler pre-processor will not re expand the macro that you define. That is it will blindly replace whatever string is found in the macro statement with the string that it finds in the definition. For example, Can we have recursive macros? or Macro recursive expansion to a sequence and C preprocessor, recursive macros

That is, recursive(a,b,c,d) will be expanded to a:recursive(b,c,d) and the pre-processor will then continue to the next line in the base code. It will not loop around to try to continue to expand the string (see the links that I cited).

Community
  • 1
  • 1
sabbahillel
  • 4,357
  • 1
  • 19
  • 36
  • 1
    "it will blindly replace whatever string is found in the macro statement with the string that it finds in the definition". Well this is exactly what I want. But it doesn't do it here! There is clearly the string `recursive(b,c,d)` in the result, yet it is not replaced with the string in the definition of `recursive`. – gexicide Apr 07 '16 at 16:37
  • No the point is that your definition includes the string `recursive(b, c, d)` As a result it blindly copies that string into the code to be compiled. Follow the links that I show. – sabbahillel Apr 07 '16 at 18:46
  • 2
    @sabbahillel: But if the body contained a different macro, it would expand it. So it has nothing to do with "blindly copying". In fact, the preprocessor has its eye as open as it gets; it is looking for macros to expand, but carefully ignores macros already being expanded. – rici Apr 08 '16 at 00:43