The example does not actually use compound literals. (i.e. _arg's initializer would work in C89.) It does use two other C99 features, though -- variadic macros and a for-loop-scoped variable declaration. The biggest compatibility issue, though, are its use of GCC extensions:<p>- Statement expressions: e.g.: int x = ({ int y = 0; y; });<p>- If zero-args are allowed (e.g. bar()), then _args is 0-sized, which is also non-standard.<p>These GCC extensions are somewhat common. Clang has them, and (I think) EDG's frontend does too. MSVC does not have either of them, even in MSVC 2015.<p>That said, a compound literal might be a good way to remove the extension use, but as long as bar() returns void, the do-while(0) trick is also sufficient for replacing the statement expression.<p>I think this compound literal usage works:<p><pre><code> #define bar(...) (bar( \
sizeof((const char*[]) { NULL, __VA_ARGS__ }) / sizeof(const char*) - 1, \
(const char*[]) { NULL, __VA_ARGS__ } + 1))
</code></pre>
bar() results in trailing commas. My impression is that C99 allows them in array initializers. (I saw an example in the n1256 C draft.) I don't recall whether C89 also had them. __VA_ARGS__ is expanded twice, but I think that's OK, because sizeof() only evaluates its operand when it has VLA type, and it never will. This code will work in MSVC 2013 (if not earlier).
The presented example will work only if the actual arguments are all of the same type. For more general usage, namely printf() and its variants, the variadic macro fails.
For what it's worth, C++ has a better way to do this.<p><a href="http://en.cppreference.com/w/cpp/language/parameter_pack" rel="nofollow">http://en.cppreference.com/w/cpp/language/parameter_pack</a><p>You might want to skip down to the example, a type safe printf.
I should note that if you just want to get the number of arguments for a call to a varargs function rather than trust people to terminate the arguments with NULL properly, you can do this with the C99 preprocessor:<p>#define foo(...) foo(PP_NUM_ARGS(__VA_ARGS__), __VA_ARGS__)<p>where PP_NUM_ARGS is a macro to determine the number of arguments; you can find such a macro easily by searching.
Of course you could just do #define foo(...) foo(__VA_ARGS__, NULL), but this lets you include NULL values in the list.<p>Since the count takes up the first argument to the actual varargs function, you can call it with zero arguments. No type checking, though as mentioned above you might be able to do something interesting about that with _Generic.
Using macro fails if I happen to pass a variable named _args as one of the arguments to bar(). Is there any clever trick to simulate gensym in C macro?