How does the C preprocessor handle circular dependencies?

CLinuxGccC Preprocessor

C Problem Overview


I want to know how the C preprocessor handles circular dependencies (of #defines). This is my program:

#define ONE TWO 
#define TWO THREE
#define THREE ONE

int main()
{
	int ONE, TWO, THREE;
	ONE = 1;
	TWO = 2;
	THREE = 3;
	printf ("ONE, TWO, THREE = %d,  %d, %d \n",ONE,  TWO, THREE);
}

Here is the preprocessor output. I'm unable to figure out why the output is as such. I would like to know the various steps a preprocessor takes in this case to give the following output.

# 1 "check_macro.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "check_macro.c"

int main()
{
 int ONE, TWO, THREE;
 ONE = 1;
 TWO = 2;
 THREE = 3;
 printf ("ONE, TWO, THREE = %d,  %d, %d \n",ONE, TWO, THREE);
}

I'm running this program on linux 3.2.0-49-generic-pae and compiling in gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5).

C Solutions


Solution 1 - C

While a preprocessor macro is being expanded, that macro's name is not expanded. So all three of your symbols are defined as themselves:

ONE -> TWO -> THREE -> ONE (not expanded because expansion of ONE is in progress)
TWO -> THREE -> ONE -> TWO (        "                         TWO      "        )
THREE -> ONE -> TWO -> THREE (      "                         THREE    "        )

This behaviour is set by §6.10.3.4 of the C standard (section number from the C11 draft, although as far as I know, the wording and numbering of the section is unchanged since C89). When a macro name is encountered, it is replaced with its definition (and # and ## preprocessor operators are dealt with, as well as parameters to function-like macros). Then the result is rescanned for more macros (in the context of the rest of the file):

> 2/ If the name of the macro being replaced is found during this scan of the replacement list (not including the rest of the source file’s preprocessing tokens), it is not replaced. Furthermore, if any nested replacements encounter the name of the macro being replaced, it is not replaced…

The clause goes on to say that any token which is not replaced because of a recursive call is effectively "frozen": it will never be replaced:

> … These nonreplaced macro name preprocessing tokens are no longer available for further replacement even if they are later (re)examined in contexts in which that macro name preprocessing token would otherwise have been replaced.

The situation which the last sentence refers rarely comes up in practice, but here is the simplest case I could think of:

#define two one,two
#define a(x) b(x)
#define b(x,y) x,y
a(two)

The result is one, two. two is expanded to one,two during the replacement of a, and the expanded two is marked as completely expanded. Subsequently, b(one,two) is expanded. This is no longer in the context of the replacement of two, but the two which is the second argument of b has been frozen, so it is not expanded again.

Solution 2 - C

Your question is answered by publication ISO/IEC 9899:TC2 section 6.10.3.4 "Rescanning and further replacement", paragraph 2, which I quote here for your convenience; in the future, please consider reading the specificaftion when you have a question about the specification.

> If the name of the macro being replaced is found during this scan of the replacement list (not including the rest of the source file’s preprocessing tokens), it is not replaced. Furthermore, if any nested replacements encounter the name of the macro being replaced, it is not replaced. These nonreplaced macro name preprocessing tokens are no longer available for further replacement even if they are later (re)examined in contexts in which that macro name preprocessing token would otherwise have been replaced.

Solution 3 - C

https://gcc.gnu.org/onlinedocs/cpp/Self-Referential-Macros.html#Self-Referential-Macros answers the question about self referential macros.

The crux of the answer is that when the pre-processor finds self referential macros, it doesn't expand them at all.

I suspect, the same logic is used to prevent expansion of circularly defined macros. Otherwise, the preprocessor will be in an infinite expansion.

Solution 4 - C

In your example you do the macro processing before defining variables of the same name, so regardless of what the result of the macro processing is, you always print 1, 2, 3!

Here is an example where the variables are defined first:

#include <stdio.h>
int main()
{
    int A = 1, B = 2, C = 3;
#define A B
#define B C
//#define C A
    printf("%d\n", A);
    printf("%d\n", B);
    printf("%d\n", C);
}

This prints 3 3 3. Somewhat insidiously, un-commenting #define C A changes the behaviour of the line printf("%d\n", B);

Solution 5 - C

Here's a nice demonstration of the behavior described in rici's and Eric Lippert's answers, i.e. that a macro name is not re-expanded if it is encountered again while already expanding the same macro.

Content of test.c:

#define ONE 1, TWO
#define TWO 2, THREE
#define THREE 3, ONE

int foo[] = {
  ONE,
  TWO,
  THREE
};

Output of gcc -E test.c (excluding initial # 1 ... lines):

int foo[] = {
  1, 2, 3, ONE,
  2, 3, 1, TWO,
  3, 1, 2, THREE
};

(I would post this as a comment, but including substantial code blocks in comments is kind of awkward, so I'm making this a Community Wiki answer instead. If you feel it would be better included as part of an existing answer, feel free to copy it and ask me to delete this CW version.)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondeepakView Question on Stackoverflow
Solution 1 - CriciView Answer on Stackoverflow
Solution 2 - CEric LippertView Answer on Stackoverflow
Solution 3 - CR SahuView Answer on Stackoverflow
Solution 4 - CM.MView Answer on Stackoverflow
Solution 5 - CIlmari KaronenView Answer on Stackoverflow