I was looking at the program at http://www0.us.ioccc.org/1988/westley.c, mentioned in another SO answer - it's supposed to print the value of pi, about 3.142, but when I compile it and run it I get 0.250
. It looks like when the GCC preprocessor (both 4.1.2 and 3.4.6 tested) runs on the code, it converts
#define _ -F<00||--F-OO--;
_-_-_
to
-F<00||--F-OO--;- -F<00||--F-OO--;- -F<00||--F-OO--;
but I think, for the program to work, it should be
-F<00||--F-OO--;--F<00||--F-OO--;--F<00||--F-OO--;
i.e. GCC is inserting an extra space before the "macro" expansion. Is that the way #define
is supposed to work? (Has that changed since 1988?)
EDIT: Also, any information about how to prevent those spaces from showing up would be appreciated.
The preprocessor operates on tokens, not strictly text. So technically it doesn't "put a space" in between, but unless you explicitly tell it to paste two tokens together with the ##
operator, it won't do it. In this case the two -
's across macro lines are counted as two different tokens - both meaning unary minus, not decrement.
see also: http://en.wikipedia.org/wiki/C_preprocessor#Token_concatenation
Only much older preprocessors didn't insert that extra space -- note that original entry was submitted over 20 years ago in 1988, before the 1989 version of the C standard was standardized. You can pass the -traditional-cpp
flag to the GCC preprocessor, which causes it to imitate the behavior of old-fashioned C preprocessors, as opposed to ISO C preprocessors.
From the C99 standard:
A preprocessing directive of the form
# define identifier replacement-list new-line
defines an object-like macro that causes each subsequent instance of the macro name to be replaced by the replacement list of preprocessing tokens that constitute the remainder of the directive.
So macros work on tokens and the whitepace is to be expected.
And you can get the output you want using the token pasting operator, ##
, but you need to use some further macro ugliness to do it:
#define PASTE2( x, y) x##y
#define PASTE( x, y) PASTE2(x, y)
#define _ -F<00||--F-OO--;
PASTE(PASTE(PASTE(PASTE(_,-),_),-),_)
So I'm not sure that this is a real answer for you.
You can use a less ugly set of macros to get the expresions you want - there will still be some spaces, but the spaces won't interfere with creating the '--
' operators:
_ PASTE(-,_) PASTE(-,_)
I still doubt that's what you want, though.
Yes, gcc is inserting extra spaces (verify by checking the stdout output of gcc -E westley.c
(. As far as I know this behavior is compliant to the standard.