Consider the following code snippet
#include
#define A -B
#define B -C
#define C 5
int main()
{
printf(\"The value of A is %d\\n\", A);
r
Pass it the -E option (Ex: gcc -E a.c
). This will output preprocessed source code.
int main()
{
printf("The value of A is %d\n", - -5);
return 0;
}
So it will introduce a space between -
and -5
hence it will be not considered as an decrement operator --
, so printf
will print 5.
GCC Documentation On Token Spacing provides the Information on Why There is an Extra Space Produced:
First, consider an issue that only concerns the stand-alone preprocessor: there needs to be a guarantee that re-reading its preprocessed output results in an identical token stream. Without taking special measures, this might not be the case because of macro substitution. For example:
#define PLUS +
#define EMPTY
#define f(x) =x=
+PLUS -EMPTY- PLUS+ f(=)
==> + + - - + + = = =
not
==> ++ -- ++ ===
One solution would be to simply insert a space between all adjacent tokens. However, we would like to keep space insertion to a minimum, both for aesthetic reasons and because it causes problems for people who still try to abuse the preprocessor for things like Fortran source and Makefiles.
For now, just notice that when tokens are added (or removed, as shown by the EMPTY example) from the original lexed token stream, we need to check for accidental token pasting. We call this paste avoidance. Token addition and removal can only occur because of macro expansion, but accidental pasting can occur in many places: both before and after each macro replacement, each argument replacement, and additionally each token created by the
#
and##
operators.