[cfe-dev] #define behavior

Hartmut Kaiser hartmut.kaiser at gmail.com
Wed Dec 5 06:04:00 PST 2007


> > Here's an interesting question that occurred in one of the OCCC 
> > entries that I was compiling with clang. This program:
> 
> I would hope OCCC entries would be valid C.
> 
> > $ cat d.c
> > #define x =
> > 
> > int foo(int *k) {
> >    return *k *x 37;
> > }
> > 
> > Generates this:
> > 
> > $ clang -ast-print d.c -triple=i686-apple-darwin9 typedef char 
> > *__builtin_va_list;
> > d.c:4:14: error: expected expression
> >    return *k *x 37;
> >               ^
> > 
> > int foo(int *k) {
> > }
> > 
> > 1 diagnostic generated.
> > 
> > GCC also balks at this. It appears that there's a space 
> being inserted 
> > after the "*" and before the "=" that "x" becomes. Is this expected?
> 
> Standard C works on tokens, not text, so the code is invalid as
> * and = are two separate tokens.

The preprocessor works on preprocessor tokens (translation phase 4), which
are different from the tokens the compiler is working on. The preprocessor
tokens are converted into tokens at translation phase 7 only. Any
preprocessor token not matching the syntax of a token is an error at this
point.

Further, IIUC concatenating two tokens (using ##) forming another (invalid)
pp token results in undefined behaviour in C90/C++ but is allowed in
C99/C++09. Gcc issues a warning here (I'm not sure about clang) for C90/C++.

Juxtapositioning two preprocessor tokens generally doesn't create a new
preprocessor token. So the two preprocessor tokens '*' and '=' are converted
to tokens separately (in translation step 7), resulting in the syntax error
above.

When the textual representation of the preprocessed input is to be generated
(i.e. gcc -E) all good preprocessors _insert_ additional whitespace between
two preprocessor tokens, which otherwise would form another token based on
juxtaposition, just to avoid creating the syntax of a different token from
juxtapositioning two preprocessor tokens. 

IMHO, gcc and clang (and FWIW, wave) behave correctly.

Regards Hartmut







More information about the cfe-dev mailing list