G++ preprocessor problem with unary ## -- summary

Dave Martindale davem@cs.ubc.ca
Wed Mar 21 09:03:00 GMT 2001


Summary of the problem: a particular header file in the LEDA software
package uses "##" in an unusual way.  There is a #defined macro that
expands to a variable-length list of comma-separated words, and this is
then passed down through two more levels of macro calls *as a single
argument* by using "##" in front of the parameter whose value is the list.

The "##" prevents the list from being rescanned and thus turned into
multiple arguments.  But, as Zack Weinberg pointed out, this use of "##"
without actually pasting tokens is not a properly-defined behaviour of
the C preprocessor, and in fact the result is explicitly undefined.

Older versions of gcc, plus many of the other c++ compilers LEDA is used
with, apparently do provide the desired behaviour of "##".  But the "gcc
2.96" supplied with Red Hat 7 flags this use with a warning and ignores it.
This behaviour is apparently the way gcc 3.0 is expected to work as well.

I eventually just rewrote the header file so that the macro expansion
that produces the list is done at the lowest level, eliminating the need
for the "unary ##" entirely.

After doing this, I noticed that the LEDA authors must have known about
the problem already, because the header file which #includes the troublesome
file has a special check for DECCXX.  If that symbol is defined, the outer
header file includes a pre-expanded version of the troublesome file rather
than the "normal" one.  This says to me that they *knew* the code didn't
work properly on at least one compiler, but rather than fixing it at the
source level they built an ugly workaround instead.

	Dave




More information about the Gcc-bugs mailing list