This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: gcc 3.0.2 preprocessor token stringization fails


On Mon, Oct 29, 2001 at 12:47:36PM -0800, David Thompson wrote:
> 
> Hi,
> 1) This source code shows a preprocessor failure for gcc-3.0.1
> and gcc-3.0.2 but works correctly in gcc-2.95.3.  Although I am
> using a sun->linux cross compiler, I notice the same failure on
> a native linux gcc-3.0.2 compiler as well.
>   --begin-source: f.c--
>   #define CONCAT2(x,y)        x##y
>   #define CONCAT3(x,y,z)      x##y##z
>   #define QUOTE(macro)        #macro
>   #define QUOTE_MACRO(macro)  QUOTE(macro)
>   #define DEFINE_DEBUGGER(defaultLevel, msgPrefix) \
>      _DEFINE_DEBUGGER(DEBUG_MODULE_NAME, defaultLevel, msgPrefix)
>   #define _DEFINE_DEBUGGER(name, defaultLevel, msgPrefix) \
>     static char *CONCAT3(p,name,MsgPrefix) = \
>     CONCAT3("<",QUOTE_MACRO(name),"> ");
>   #define DEBUG_MODULE_NAME SFTP
>   DEFINE_DEBUGGER(9,"SFTP")

This is a classic case of unnecessary token pasting.  Your example
winds up as (the equivalent of)

   "<" ## "SFTP" ## "> "

But you cannot paste two string literals together with ##.  You get
the single token {"<""SFTP"} which is not a valid preprocessing token.
(You do _not_ get what you probably expected, i.e. "<SFTP".)  The C
standard describes this as undefined behavior.  GCC 2.95 would silently
ignore the ## when this happened; 3.0 complains.

Also, the QUOTE_MACRO invocation in 

   ... CONCAT3 (..., QUOTE_MACRO(...), ...) ...

is _not_ supposed to be expanded according to the standard.  This is
a known, obscure, bug in the 2.95 preprocessor.

All you have to do to fix your code is remove the CONCAT3 on the line
defining the string:

#define _DEFINE_DEBUGGER(name) \
   static const char CONCAT3(p,name,MsgPrefix)[] = \
     "<" QUOTE_MACRO(name) "> "

which will expand to e.g.

static const char pSFTPMsgPrefix[] = "<" "SFTP" "> ";

which is the _same thing_ that you were getting with 2.95.  You may not
be aware of the rule that adjacent string literals are combined into a
single string constant.  They are, and that is why your code worked in
the first place.
    
Note that the second two arguments to _DEFINE_DEBUGGER in your original
code are unused, I suspect this is an accident...

zw


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]