This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: gcc 3.0.2 preprocessor token stringization fails
- To: David Thompson <David dot Thompson at efi dot com>
- Subject: Re: gcc 3.0.2 preprocessor token stringization fails
- From: Zack Weinberg <zack at codesourcery dot com>
- Date: Mon, 29 Oct 2001 13:20:59 -0800
- Cc: "'gcc-bugs at gcc dot gnu dot org'" <gcc-bugs at gcc dot gnu dot org>
- References: <D9F6B9DABA4CAE4B92850252C52383AB0120C1A3@ex-eng-corp>
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