Reputation: 1663
I am trying to figure out how to write a preprocessor macro which will "stringify" its argument only if an argument is present
For example:
STRINGIFY(foo) -> "foo"
STRINGIFY() ->
In my very basic example:
#define STRINGIFY(x) #x
Calling STRINGIFY() results in "" rather than nothing at all (which is what I want)
How can this be achieved?
EDIT
As An example of why I want this behavior, I am using the macro to generate an initializer for an array of strings as such
const char* STRINGS[] = {MAP_LIST(STRINGIFY, __VA_ARGS__)};
Where MAP_LIST comes from the following project: https://github.com/swansontec/map-macro
If my VA_ARGS lsit has items in it, you end up with, for example, the following:
const char* STRINGS[] = {"a", "b", "c"};
But if VA_ARGS is empty, I end up with:
const char* STRINGS[] = {""};
Because, when you "stringify" an empty argument, it gives you an empty string.
Upvotes: 0
Views: 486
Reputation: 141493
how to write a preprocessor macro which will "stringify" its argument only if an argument is present
You can do a variadic macro and put a macro with ()
that will expand to a comma (or specific count of commas) and put __VA_ARGS__
between that macro and ()
and then overload on the count of arguments.
#define TRIGGER_PARENTHESIS(...) ,
#define STRINGIFY_0()
#define STRINGIFY_1(a) #a
#define STRINGIFY_N2(_0,_1,N,...) STRINGIFY_##N
#define STRINGIFY_N(...) STRINGIFY_N2(__VA_ARGS__)
#define STRINGIFY(...) STRINGIFY_N(TRIGGER_PARENTHESIS __VA_ARGS__ (),0,1)(__VA_ARGS__)
See A way to count the number of __VA_ARGS__ arguments, including 0, without compiler specific constructs for a more roboust method.
With a compiler with __VA_OPT__
and in newer C++, it's just:
#define STRINGIFY(...) __VA_OPT__(#__VA_ARGS__)
As noted in the comments, your use case is invalid. If the result of MAP_LIST(STRINGIFY, __VA_ARGS__)
would be empty, then it would result in:
const char* STRINGS[] = {};
which is invalid C code, because Is an empty initializer list valid C code? and What happens if I define a 0-size array in C/C++? . Both zero sized arrays and empty initializer lists are extensions in GNU C compiler.
Upvotes: 1