0

I just followed a tutorial that involved doing CPP macros to implement a Debug system in a program. One great behavior of the macros is being recursive, making it possible to put a macro inside another macro like below:

#define MACRO1 "World"
#define MACRO2 printf("Hello %s\n",MACRO1);
#include<stdio.h>
#include<stdlib.h>

int main(int argc, char *argv[]){
    MACRO2
    return 0;
}

Output: Hello World

The below also seems to work:

#define MACRO2 printf("Hello %s\n",MACRO1);
#define MACRO1 "World"
#include<stdio.h>
#include<stdlib.h>

int main(int argc, char *argv[]){
    MACRO2
    return 0;
}

So just to understand, does CPP first reads all #define X to make a list of declared macros, to then substitute the macros that are inside other macros, avoiding the "chicken and egg" issue on pre-processing?

I think that makes sense, considering pre-processing is a one-time only process (during compilation), not happening in real time. So it shouldn't matter where in the code a macro was defined, but actually if it was defined at all.

Having a 3000 lines code and only in the last line defining a macro used in the code would be valid then?

Thank you in advance!

IanC
  • 1,968
  • 14
  • 23
  • Possible duplicate of [How many passes does the C preprocessor make?](http://stackoverflow.com/questions/13442028/how-many-passes-does-the-c-preprocessor-make) – Eugene Sh. Aug 08 '16 at 15:57

1 Answers1

1

What actually happens is that the recursive substitution happens only when a macro is used, not when it's defined.

So at

#define MACRO2 printf("Hello %s\n",MACRO1);

the preprocessor just memorizes that MACRO2 expands as the 7 tokens printf, (, "Hello %s\n", ,, MACRO1, ), and ;. At this point it doesn't care which if any of those tokens are macros.

At the point in main where you do

MACRO2

the preprocessor expands the macro to those seven tokens, and then checks to see whether the token stream contains any more macros that can be expanded again. It notices MACRO1 and substitutes the token "World". At this point it checks again, but there are no more macros for expansion.

You'll still run into problems if you try to use a macro before it's been #defined.

aschepler
  • 70,891
  • 9
  • 107
  • 161