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


Zack Weinberg wrote:
> macro(a, b)
> 
> is permitted by GCC, and has the same expansion as
> 
> macro(a, b, )

Not quite, as you point out below.

> 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, ).

Good, this is like older versions of GCC.

> 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.

Cool.

For other tokens, perhaps C99 requires that the token preceding
##__VA_ARGS__ is not deleted, if it is possible to paste them?

> 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.

Btw, older versions of GCC also distinguish between no rest args, and
an empty one.  I expect you know this.

> 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.

Perhaps more sensible logic would be to warn if the tokens are
non-pastable and you did not delete the preceding token?  ", ## rest"
naturally does not require a warning in that case, but other cases where
the previous token is not deleted would trigger the warning.  (I don't
know which cases they are but you alluded to them earlier).

> 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.

It's code I've been working with for years, that worked fine over many
many versions of GCC and has recently broken between GCC 2.95.2 and GCC 2.96.

If GCC _has_ to change to comply with a standard, fair enough but I
think that in this case there is a genuine bug somewhere in the
preprocessor, to do with nested varargs processing.  My macros happen to
trigger it.  Hopefully Neil can work out what's going on.

thanks,
-- Jamie

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