Issue
How does the C preprocessor handle multiple macros? I searched it over here and Google too, but I was not able to understand the exact rule that should be followed. The following code:
#define ABC xYz
#define xYz ABC
int main()
{
int ABC;
int xYz;
}
in gcc, generates file preprocessor.i like this:
# 1 "preprocessor.c"
# 1 "<command-line>"
# 1 "preprocessor.c"
int main()
{
int ABC;
int xYz;
}
seems nothing is replaced here. And other code:
#define ABC kkk
#define xYz ABC
int main()
{
int ABC;
int xYz;
}
generates output like this:
# 1 "preprocessor.c"
# 1 "<command-line>"
# 1 "preprocessor.c"
int main()
{
int kkk;
int kkk;
}
So how are all these happening?
Solution
The behaviour in the first case is correct because once a macro has been used once in an expansion, it can't be used again. So, the preprocessor first turns the ABC
in int ABC;
into int xYz;
, and then it turns the xYz
back into ABC
, but there are no further transforms possible because both macros have been used once.
The second code behaves correctly too, of course. The int ABC;
is turned directly into int kkk;
. The int xYz;
is turned into int ABC;
and then into int kkk;
.
You can look at How many passes does the C preprocessor make? for some more information.
Does the preprocessor do macro substitution one by one, like first the expansion corresponding to
#define ABC xYz
is done then it goes for#define xYz ABC
, or does it handle both macros in one go? If the first is the case then the output should beint ABC
andint ABC
.
The sequence in which the macros are defined is immaterial. The preprocessor tokenizes the input, and for each symbol, it looks to see whether there is a macro defined. If there is a macro, it applies the macro expansion and then marks it as 'used' (for the current token expansion). It then rescans the replacement text, looking for tokens again, and applying macros again (unless they're marked 'used'). The 'marking as used' prevents infinite recursion in macro expansion. When it finishes rescanning the replacement text, all the 'used' macros are marked 'unused' again.
Answered By - Jonathan Leffler Answer Checked By - Dawn Plyler (WPSolving Volunteer)