Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overloading Macro on Number of Arguments

I have two macros FOO2 and FOO3:

#define FOO2(x,y) ... #define FOO3(x,y,z) ... 

I want to define a new macro FOO as follows:

#define FOO(x,y) FOO2(x,y) #define FOO(x,y,z) FOO3(x,y,z) 

But this doesn't work because macros do not overload on number of arguments.

Without modifying FOO2 and FOO3, is there some way to define a macro FOO (using __VA_ARGS__ or otherwise) to get the same effect of dispatching FOO(x,y) to FOO2, and FOO(x,y,z) to FOO3?

like image 521
Andrew Tomazos Avatar asked Aug 01 '12 14:08

Andrew Tomazos


People also ask

How many arguments can a macro have?

For portability, you should not have more than 31 parameters for a macro. The parameter list may end with an ellipsis (…).

Can macro be overloaded?

Macros cannot be overloaded and the (...) mechanism cannot do what you want.

Can you supply more than one argument in a macro call?

Yes. If you try untouchable(foo,first) you get an error because the macro only sees two parameters but was expecting 4.

How many arguments we pass in macro definition?

The macro definition can include macro arguments, which can be assigned specific values in the macro call. There are two types of arguments: keyword and positional. Keyword arguments are assigned names in the macro definition; in the macro call, they are identified by name.


1 Answers

Simple as:

#define GET_MACRO(_1,_2,_3,NAME,...) NAME #define FOO(...) GET_MACRO(__VA_ARGS__, FOO3, FOO2)(__VA_ARGS__) 

So if you have these macros, they expand as described:

FOO(World, !)         // expands to FOO2(World, !) FOO(foo,bar,baz)      // expands to FOO3(foo,bar,baz) 

If you want a fourth one:

#define GET_MACRO(_1,_2,_3,_4,NAME,...) NAME #define FOO(...) GET_MACRO(__VA_ARGS__, FOO4, FOO3, FOO2)(__VA_ARGS__)  FOO(a,b,c,d)          // expands to FOO4(a,b,c,d) 

Naturally, if you define FOO2, FOO3 and FOO4, the output will be replaced by those of the defined macros.

like image 149
netcoder Avatar answered Sep 20 '22 10:09

netcoder