This is the mail archive of the gcc@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: Varargs macros subtly broken


On Mon, Sep 25, 2000 at 06:42:54PM +0200, Jamie Lokier wrote:
> Zack Weinberg wrote:
> > > Ah yes, that is one form of a varargs bug I've been meaning to report.
> > > I've got macros which work fine with GCC 2.95, but don't work with _or_
> > > without -traditional now.  (Sorry, I'll try to provide an example
> > > tomorrow).
> > 
> > Please do provide an example.  I wouldn't be surprised to find genuine
> > bugs in the varargs macro code.
> > 
> > The new semantics are not that different; in most cases it will be possible
> > to convert macros.
> 
> I see that now.  Attached are examples of macros that used to work but
> are broken now.  Preprocessing fails with errors.
> 
> I've included examples using the old syntax, and also converted ones for
> __VA_ARGS__ syntax.  Both exhibit the same problems with the current
> preprocessor

Let me go over the intended semantics.  There are three extensions in
GCC to C99 vararg macros.  First:

#define macro(a, b, ...)  a, b, __VA_ARGS__

means precisely the same as

#define macro(a, b, __VA_ARGS__...) a, b, __VA_ARGS__

and you may replace __VA_ARGS__ by any identifier:

#define macro(a, b, rest...) a, b, rest

In other words, __VA_ARGS__ is the default rest-arg name, and you can
use something more euphonious if you wish.  Note that this means that
__VA_ARGS__ is not special outside of vararg macros - contrary to C99
where it is always reserved.  Also, the other two extensions apply
whether or not you give the rest argument a name.

Second: given

#define macro(a, b, rest...) a, b, rest

then

macro(a, b)

is permitted by GCC, and has the same expansion as

macro(a, b, )

However, if -pedantic is on, a warning issues.

Third: if you write

#define macro(a, b, rest...) a, b, ## rest

and then use macro with only two arguments, then the comma after b is
deleted.  This does not happen if you write macro(a, b, ).  You can
only count on this behavior if the token immediately preceding the ##
is a comma.  Other immediate predecessors may or may not be deleted
depending on undocumented implementation details.

This is the biggest change from GCC 2.95.  Previous versions of the
preprocessor deleted the sequence of nonwhitespace characters
immediately before the ##, no matter what they were.  This version
only deletes one token, and only does so if you give no rest args at
all; an empty rest arg doesn't trigger deletion.  And you cannot rely
on the preceding token being deleted unless it is a comma.

Also, there's a new warning, which issues whenever the tokens on
either side of ## cannot be glued into one token.  This warning is on
by default, and may be suppressed by -Wno-paste.  A macro written to
use the third extension would normally trigger this warning.  However,
as a special case, the warning is suppressed for ", ## rest" where
rest is a rest argument.  If you put something else before the ## the
warning may or may not happen.

I do not have time to investigate your example in detail, but my
immediate reaction is that you're trying to do things outside of cpp's
intended scope.  If you want M4, you know where to find it.

zw

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