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: G++ preprocessor problem with unary ##


On Tue, Mar 20, 2001 at 07:43:33AM +0000, Neil Booth wrote:
> Dave Martindale wrote:-
> 
> > I use a large C++ library called LEDA.  It compiled and ran OK using
> > g++ 2.95, but parts of it will not compile under 2.96.  The problem is
> > in the handling of a particular use of the "##" token pasting operator
> > in the preprocessor.  Here is a simplified example of the code that
> > causes the problem:
> 
> This has come up before.
> 
> Simply deleting the ## should work.  There is no such thing as unary ##;
> just like there is no such thing as unary division :-)  ## pastes two
> surrounding tokens to form a single token; if it doesn't form a single
> token it is an error in the source code.

Um, he said he'd simply deleted the ## and it didn't work.  I believe
I know why.

There are two effects of ##.  The obvious one is, it pastes together
the two tokens on either side of it.  The not-so-obvious one is, it
inhibits pre-expansion of both sides, if they are formal parameters to
the macro.  This sample code wants to use ## to suppress formal
parameter pre-expansion, but *not* to paste tokens.

Unfortunately the C++ standard does not countenance using ## just to
suppress formal parameter pre-expansion.  The key bit is paragraph 3
of [cpp.concat], section 16.3.3 of C++98; this section is identical to
C99 section 6.10.3.3.

3  For both object-like and function-like macro invocations, before
   the replacement list is reexamined for more macro names to replace,
   each instance of a ## preprocessing token in the replacement list
   (not from an argument) is deleted and the preceding preprocessing
   token is concatenated with the following preprocessing token.
   [...] If the result is not a valid preprocessing token, the
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   behavior is undefined. The resulting token is available for further
   ^^^^^^^^^^^^^^^^^^^^^^
   macro replacement. The order of evaluation of ## operators is
   unspecified.

Emphasis is mine.  If ## is used in a context where its result is not
a valid single pp-token, the compiler is permitted to do absolutely
anything it sees fit.  It may reject the code outright; it may
interpret it differently from your expectations, producing
compile-time or run-time failures; it may do what you expected it to.
GCC chooses to issue a warning and pretend the ## wasn't there.

The sample code does exactly this, because it wants to suppress
pre-expansion.  But you can't have pre-expansion without token
pasting, in standard C++.

zw


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