About Me

My photo
Christian. (That means that I know that Jesus is Lord!) Programmer. Gamer. Weak 3D artist. Geek.

Thursday, 16 July 2009

I didn't know about variadic macros!

It's become quite fashionable of late to cite Wikipedia as the place not to get information from.

At work yesterday I was working with C++/C macros of the standard #define form, you know, like this:

#define MY_FUNCTION myFunction("test parameter")

so that if I use the define MY_FUNCTION in my code, the compiler will swap in 'myFunction("test parameter")' for me.

However, as C++/C programmers out there will know, you can offer default parameter values for a function, so what if my function 'myFunction' has been originally defined like this:

void myFunction(std::string inputString = "test");

Well, that means that the function will have a default input string of test if one hasn't been specified, by calling the function like so:

myFunction();

The issue then is, how do I call myFunction from a defined macro with and without wanting to pass parameters into the macro? I mean, it's easy to define the macro to take a parameter but how do I make the parameter optional? For instance, to add macro parameters do this:

#define MY_FUNCTION(x) myFunction(x)

This way, the parameter 'x' passed into the define will then be automatically passed into the function 'myFunction' as it's first parameter.

But this is the clever part coming up..
If I want to maybe specify an optional parameter I can do it like this:

void myFunction(std::string = "test");
#define MY_FUNCTION(...) myFunction(__VA_ARGS__)

This way, my original C++ function of myFunction receives a single argument of type std::string, which, if it isn't passed in, defaults to being a string of characters as 'test'.
Now, the define will pass on a variable amount of arguments to the function as necessary (so I could pass 4 or 5 arguments if I wanted to, though the function itself would complain because it only accepts one argument.)

This way I can create a macro definition of my function that can accept optional parameters! Apparently this is called a 'variadic macro' and is part of the ISO C99 C standard. I didn't know that and thought it was pretty cool!

You can read more about it here.

The point of this post is mainly for record for myself so I know what this does and how to implement it in future - I don't think any of the other coders in our company knew how to do this, so I thought it was best to document it for future reference.

Geeks out there, I hope that helped.

1 comment:

Matt Davies said...

You should avoid using macros altogether. In the example you show you can easily accomplish the same thing with an inline template/non-template function. You will get better compiler support and avoid all the scoping problems you have with macros.