1

Trying to get this working in VS2013 (see Variadic macro trick and C++ preprocessor __VA_ARGS__ number of arguments).

It's not a duplicate afaik (versions posted elsewhere only work with GCC).

Any ideas what's wrong with this? I'm almost there...

#define _EXPAND(x) x
#define _VA_NARGS_IMPL(_1_, _2_, _3_, _4_, _5_, N, ...) N
#define _VA_NARGS_IMPL2(...) _EXPAND(_VA_NARGS_IMPL(__VA_ARGS__, 4, 3, 2, 1, 0))
#define _PUSH_X_FRONT(...) X, __VA_ARGS__
/*
Returns the number of arguments specified.
#ifndef _MSC_VER
  #define VA_NARGS(...)  _VA_NARGS_IMPL2(X,##__VA_ARGS__)
*/
#define VA_NARGS(...)  _VA_NARGS_IMPL2(_PUSH_X_FRONT(__VA_ARGS__))

// testing is gewd
static_assert(VA_NARGS() == 0, "VA_NARGS() failed for 0 arguments");
static_assert(VA_NARGS(one, two, three, four) == 4, "VA_NARGS() failed for 4 arguments");

#define _VARARG_IMPL2(N, Macro, ...) Macro##N(__VA_ARGS__)
#define _VARARG_IMPL(N, Macro, ...) _VARARG_IMPL2(N, Macro, __VA_ARGS__)
// Helper function for variadic macros with per-argument processing.
#define VARARG(Macro, ...) _VARARG_IMPL(VA_NARGS(__VA_ARGS__), Macro, __VA_ARGS__)


#define _Quote1(x) #x
#define _Quote2(x, ...) #x, _Quote1(__VA_ARGS__)
#define _Quote3(x, ...) #x, _Quote2(__VA_ARGS__)
#define _Quote4(x, ...) #x, _Quote3(__VA_ARGS__)
// Treat each argument as a string literal, encompassing in quotes.
#define Quote(...) VARARG(_Quote, __VA_ARGS__)

Question:

constexpr char *a[] = { Quote(a, b) };
// WHY does the above produce {"a, b"} with msvc?
// The following produces {"a", "b"} as expected
constexpr char *a[] = { _Quote2(s, c) };
Community
  • 1
  • 1
casper.dcl
  • 13,035
  • 4
  • 31
  • 32

1 Answers1

0

It is difficult to make a real variadic macro to work in VS2013. I had something done to expand a macro to be interpreted on it's own as a new macro. The key is to make multiple level macros. It is a lot to code but for given sample it will work.

#define InitialMacro (argument1, argument2) \
DetailedMacro(argument1, argument2, argument1##_description, argument2##_description)

#define DetailedMacro (argument1, argument2, argument3, argument4)      \
L#argument1     \
L#argument2     \
L#argument3     \
L#argument4

The ideea presented here is to implement enough macros to cover all your requirement in the number of parameters nedeed. Also you can forward/update macro with aditional items on the way. Basically first macro in this example append to the second and third transmitted parameters the suffix _description resulting in another macro that will get interpreted as a macro and it will be expanded in DetailedMacro.

You could also take a look at this: msvc variadic macro expansion

Community
  • 1
  • 1
Ionut V.
  • 110
  • 7