__VA_ARGS__ extension using MSVC

I found a question on how to overload macros based on the number of arguments: Overloading a macro by the number of arguments

But as they say, it does not work using MSVC, because MSVC extends __VA_ARGS__ into one token instead of a list of arguments ( arg1, arg2, arg3 ).

They point to another question where the work is given: MSVC does not expand __VA_ARGS__ correctly, but did not explain it at all, so I cannot adapt it to my own business, since I cannot understand it.

Could you explain how this works?

+6
source share
1 answer

The workaround in question is as follows:

 #define EXPAND( x ) x #define F(x, ...) X = x and VA_ARGS = __VA_ARGS__ #define G(...) EXPAND( F(__VA_ARGS__) ) 

The idea is that, given the existing variational macro F() :

 #define F(x, ...) X = x and VA_ARGS = __VA_ARGS__ 

instead of writing the desired convertible shell macro, in this case ...

 #define G(...) F(__VA_ARGS__) 

... you write G() with the optional EXPAND() macro. The actual definition of F() not a point, and in particular, for this example it does not matter that the macro extension does not lead to a valid C code. Its purpose is to demonstrate the behavior of the preprocessor with respect to macro arguments. In particular, this shows that although MSVC extends __VA_ARGS__ to one token in a variable macro, which can be bypassed by forcing a double extension.

For example, using a workaround definition, the preprocessor first extends ...

 G(1, 2, 3) 

... to ...

 EXPAND( F(1, 2, 3) ) 

... where 1, 2, 3 considered as one token. However, this tokenization does not matter when the preprocessor rescans for additional substitutions: it sees 1 , 2 , 3 as separate arguments for the F() macro and expands it as needed to create an argument for the EXPAND() macro, which is just replaces it with oneself.

If you find it strange that this works as intended, but the version without EXPAND() does not work (in MSVC), you are right.

+9
source

All Articles