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.