I guess most of you who have worked with C/C++ have an intuition of how the preprocessor works (more or less). I thought so until today, but my intuition was proved wrong. Here is the story:
Today I tried something, but I can not explain the result. First consider the following code:
#define A B
#define B A
A
B
What happens? Well, the result after compiling it with the -E flag is this:
A
B
Well, ok, maybe not what anyone would expect, but it is explainable. I guess that the preprocessor somehow figured out that there is some problem, and did nothng.
The next thing I tried was this:
#define A B
#define B A C
#define C x
A
B
Now to the, for me, unexplainable result:
A x
B x
How did this happen? I can not figure out any reasonable way of how this happened. The first command (#define A B) can not be executed, because then A would be replaced by B, and the final result should be same for both. But if it is not, then there is no way that "A x" can happen!
My question: What am I missing? Obviously I don't know the exact way of how the preprocessor works. Do you know any sources about it?
Self-Referential Macros explains. Expansion is applied deeply but stops once a macro references itself.
#define A B
#define B A C
#define C x
A -> B -> A C -> A x
B -> A C -> B x
Expansion is token by token "lazily"
Each chain of substitutions can visit any macro definition at most once. Among other things, this means that you can't have recursive macros.
The substitutions for your second example will look like this:
A --[evaluate A]--> B --[evaluate B]--> A C --[evaluate C]--> A x
B --[evaluate B]--> A C --[evaluate A,C]--> B x
During the last step of the first line, A
is not evaluated because it was already invoked previously. Similarly, in the second line, evaluation stops at B
because it has already been visited during the first step.
The relevant section of the C99 standard would be 6.10.3.4 Rescanning and further replacement.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With