Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variadic macros with zero arguments

I am working on a call macro,

#define CALL(f,...) FN(f)->call((ref(new LinkedList()), __VA_ARGS__)) 

which when called,

CALL(print,2,3,4,5); 

adds 2 3 4 5 to the linked list (, is overloaded to do so) and calls print which expects a linked list which works as expected how ever there are some calls which do not require arguments,

CALL(HeapSize); 

It still takes a linked list but an empty one, above does not work, I am trying to come up with a macro that woud work with either style?

EDIT: Digging throug gcc docs I found that adding ## before VA_ARGS removes the , when there are no arguments but with that I can not nest macros,

CALL(print,CALL(HeadSize)); 

this causes CALL not defined error how ever if I separate the the calls it works

like image 825
Hamza Yerlikaya Avatar asked May 05 '11 00:05

Hamza Yerlikaya


People also ask

How do you define variadic arguments?

Here is an example: #define eprintf(...) fprintf (stderr, __VA_ARGS__) This kind of macro is called variadic. When the macro is invoked, all the tokens in its argument list after the last named argument (this macro has none), including any commas, become the variable argument.

What is __ Va_args __ in C++?

To use variadic macros, the ellipsis may be specified as the final formal argument in a macro definition, and the replacement identifier __VA_ARGS__ may be used in the definition to insert the extra arguments. __VA_ARGS__ is replaced by all of the arguments that match the ellipsis, including commas between them.

What is the correct format for naming a macro with multiple arguments?

To create a macro with arguments, put them in parentheses separated by commas after the macro name, e.g. then BadSquare(3+4) would give 3+4*3+4, which evaluates to 19, which is probably not what we intended.

What are the macros that are designed to support variable length arguments?

To support variable length arguments in macro, we must include ellipses (…) in macro definition. There is also “__VA_ARGS__” preprocessing identifier which takes care of variable length argument substitutions which are provided to macro.


2 Answers

As for the updated question, by the use of auxiliary macro VA_ARGS like the following, the arguments will be expanded as expected.

#define VA_ARGS(...) , ##__VA_ARGS__ #define CALL(f,...) FN(f)->call((ref(new LinkedList()) VA_ARGS(__VA_ARGS__))) 
like image 158
Ise Wisteria Avatar answered Sep 25 '22 13:09

Ise Wisteria


If you're using gcc/g++ there is a way:

#define CALL(f,...) FN(f)->call((ref(new LinkedList()), ## __VA_ARGS__)) 

From the fine manual:

[...] if the variable arguments are omitted or empty, the `##' operator causes the preprocessor to remove the comma before it.

So gcc has an extension/hack specifically for the problem you are facing.

like image 28
mu is too short Avatar answered Sep 26 '22 13:09

mu is too short