Macros which accept a variable number of arguments. Now part of the AnsiCee 99 standard; long been a supported non-standard extension to various C compilers (GCC, for instance).
Of course, the CeePreprocessor is still a SteamingTurd?; and C99 doesn't change that. But VarArgMacros are a somewhat useful addition - there are many times when I have had to write things like this:
#define foo0() bar(x) #define foo1(a1) bar(x,a1) #define foo2(a1,a2) bar(x,a1,a2) #define foo3(a1,a2,a3) bar(x,a1,a2,a3) /* and so on... usually larger number of args aren't added until needed */where bar() is a vararg function, and foon are convenience macros.
Not very convenient convenience macros ;) The other portable technique is as follows:
#define foo(PARAMS) bar PARAMS foo((a)); foo((a, b)); foo((a, b, c));Note the double brackets. I think this technique is marginally better than the foon technique above.
For completeness, the C99 way is as follows:
#define foo(...) bar(__VA_ARGS__) foo(a); foo(a, b); foo(a, b, c);It's amazing it took 20 years for this to make it into the standard.
And to be fair, I missed the x parameter in the original comment. Although with respect to the original problem, the screamingly obvious:
#define foo(...) bar(x, __VA_ARGS__)will only work if foo has at least one parameter. Unless you're using GCC, in which case
#define foo(...) bar(x, ##__VA_ARGS__)will remove the comma after the x in the case of foo(), BUT THIS INNOVATION WASN'T INCLUDED IN THE C99 STANDARD, so the preprocessor will still emit something retarded in that particular circumstance.
If I were on the C standards board, I'd be pushing for adoption of C++ templates. (And that's not a throwaway comment - templates provide the C++ compiler with enough information to reason about the code it will emit, and template specialization allows the programmer to provide sensible defaults which can be overridden for specific types. The C preprocessor is still operating at the level of textual concatenation, anyway, I digress...)