Can macros be overloaded by number of arguments?

(Edit: See the end for a ready-made solution.) To get an overloaded macro, first we need a macro which selects between several implementations. This part doesn’t use a variadic macro. Then a variadic macro which generically counts its arguments produces a selector. Plugging the argument count into a dispatcher produces an overloaded macro. Caveat: This … Read more

Variadic macro trick

#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, N, …) N #define VA_NARGS(…) VA_NARGS_IMPL(__VA_ARGS__, 5, 4, 3, 2, 1) #define FOO_IMPL2(count, …) FOO ## count (__VA_ARGS__) #define FOO_IMPL(count, …) FOO_IMPL2(count, __VA_ARGS__) #define FOO(…) FOO_IMPL(VA_NARGS(__VA_ARGS__), __VA_ARGS__) FOO(a) FOO(a, b) FOO(a, b, c) The invocations are replaced by: FOO1 (a) FOO2 (a, b) FOO3 (a, b, c)

Standard alternative to GCC’s ##__VA_ARGS__ trick?

There is an argument counting trick that you can use. Here is one standard-compliant way to implement the second BAR() example in jwd’s question: #include <stdio.h> #define BAR(…) printf(FIRST(__VA_ARGS__) “\n” REST(__VA_ARGS__)) /* expands to the first argument */ #define FIRST(…) FIRST_HELPER(__VA_ARGS__, throwaway) #define FIRST_HELPER(first, …) first /* * if there’s only one argument, expands to … Read more

MSVC doesn’t expand __VA_ARGS__ correctly

Edit: This issue might be resolved by using /Zc:preprocessor or /experimental:preprocessor option in recent MSVC. For the details, please see here. MSVC’s preprocessor seems to behave quite differently from the standard specification. Probably the following workaround will help: #define EXPAND( x ) x #define F(x, …) X = x and VA_ARGS = __VA_ARGS__ #define G(…) … Read more

C++ preprocessor __VA_ARGS__ number of arguments

I usually use this macro to find a number of params: #define NUMARGS(…) (sizeof((int[]){__VA_ARGS__})/sizeof(int)) Full example: #include <stdio.h> #include <string.h> #include <stdarg.h> #define NUMARGS(…) (sizeof((int[]){__VA_ARGS__})/sizeof(int)) #define SUM(…) (sum(NUMARGS(__VA_ARGS__), __VA_ARGS__)) void sum(int numargs, …); int main(int argc, char *argv[]) { SUM(1); SUM(1, 2); SUM(1, 2, 3); SUM(1, 2, 3, 4); return 1; } void sum(int numargs, … Read more