1

I'd like to use a macro like the following:

#define x(...) y(a,##__VA_ARGS__,b)

To expand like so:

x();   ->   y(a,b);
x(1);  ->   y(a,1,b);

With -std=gnu99, it works perfectly.

With -std=c99 however, it looks like this:

x();   ->   y(a,,b);
x(1);  ->   y(a,1,b);

The ## is making no difference – it's not swallowing the comma.

In other usages under C99, e.g. #define x(a,...) y(a,##__VA_ARGS__), comma-swallowing works fine.

What can I do, if anything, to get the desired comma-swallowing behaviour under clang's -std=c99, either with the GNU extension ## or by some other method?

Max
  • 2,760
  • 1
  • 28
  • 47
  • So how does that work on the implementation side (i.e. how does the function consume the variable arguments)? – trojanfoe May 13 '16 at 09:27
  • @trojanfoe Thanks for the comment, but that's not within the scope of this question. (This is not an XY question.) – Max May 13 '16 at 09:30
  • @trojanfoe Sure: I'm using this macro to call `a()` if there are no arguments, or `b(x)` if there is one argument: `GET_MACRO(_0, ##__VA_ARGS__, b, a)(__VA_ARGS__)`. – Max May 13 '16 at 09:35
  • 1
    related: https://stackoverflow.com/questions/5588855/standard-alternative-to-gccs-va-args-trick – Jens Gustedt May 13 '16 at 09:51

3 Answers3

3

That's expected behaviour. There is no standard way to swallow the comma.

Fortunately, gcc, clang and xlc support the ##__VA_ARGS__ gnu extension, and msvc swallows the comma automatically.

If you don't want to rely on above mentioned language extensions, the idiomatic ISO C90 way to get variable argument macros was like this:

#define x(args) y args

/* notice the extra parantheses */
x((a, b, c, d));

If you don't want to use either of these solutions, you can always employ argument counting, as answered here.

Community
  • 1
  • 1
Leandros
  • 16,805
  • 9
  • 69
  • 108
1

Yes, ##__VA_ARGS__ is a GNU extension.

Samuel Peter
  • 4,136
  • 2
  • 34
  • 42
  • See my question: "In other usages under C99, e.g. `#define x(a,...) y(a,##__VA_ARGS__)`, comma-swallowing works fine." – Max May 13 '16 at 09:25
  • And also, I'm asking if there is any way, using `##__VA_ARGS__` or not. – Max May 13 '16 at 09:27
  • Just tried it on clang with `std=c99 -pedantic` and the line `#define x(a,...) y(a,##__VA_ARGS__)` gave the warning `Token pasting of ',' and __VA_ARGS__ is a GNU extension`. So I think that getting the comma swallowing behavior under C99 was specific to your compiler / command line arguments. It is not standard C99. – Samuel Peter May 13 '16 at 09:39
  • Sorry, I should have been clearer. I'm aware it's not standard C99. I'm looking for either a C99-compliant way that works, or a way I can leverage gcc/clang's `-stc=c99` plus `##` to do it. – Max May 13 '16 at 09:43
  • On GCC you can use --std=gnu99 to work with c99 and GNU extension. https://gcc.gnu.org/onlinedocs/gcc-5.1.0/gcc/Standards.html#Standards – Dave Kok May 13 '16 at 09:51
  • 1
    I think the only way to do it in a C99 or C11-compliant way is to include the comma in the macro call, i.e. `#define x(...) y(a __VA_ARGS__,b)`, so `x(,)` --> `y(a,b)`, and `x(,1)` --> `y(a,1,b)`. Or you could define `x` slightly differently so that it is called with the extra comma at the end of the argument list instead of the start of the argument list. Either way is equally ugly, and not really what you want. You can either use the GCC extension, or wait for a new revision of the C standard, which may or may not define a standard way to swallow the comma! – Ian Abbott May 13 '16 at 10:13
0

As you describe, the following pattern works fines.

#define x(a,...) y(a,##__VA_ARGS__)

After I run the following code snip, I guess ##__VA_ARGS__ will always swallow comma when the prefix args exists(such as _ in the e_x)

#define x(...) y(a,c, ##__VA_ARGS__, b)
#define e_x(_, ...) y(a, c, ##__VA_ARGS__, b)

x();
x(a);
x(a, b);

e_x();
e_x(a);
e_x(a, b);

You can get the result:

y(a,c,, b);
y(a,c,a, b);
y(a,c,a, b, b);

y(a, c, b);
y(a, c, b);
y(a, c, b, b);

Above sample works fine in my computer(both macos and linux) .

Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135