Consider this code:
#define F(x, ...) X = x and VA_ARGS = __VA_ARGS__
#define G(...) F(__VA_ARGS__)
F(1, 2, 3)
G(1, 2, 3)
The expected output is X = 1 and VA_ARGS = 2, 3
for both macros, and that's what I'm getting with GCC, however, MSVC expands this as:
X = 1 and VA_ARGS = 2, 3
X = 1, 2, 3 and VA_ARGS =
That is, __VA_ARGS__
is expanded as a single argument, instead of being broken down to multiple ones.
Any way around this?
MSVC's preprocessor seems to behave quite differently from the standard
specification.
Probably the following workaround will help:
#define EXPAND( x ) x
#define F(x, ...) X = x and VA_ARGS = __VA_ARGS__
#define G(...) EXPAND( F(__VA_ARGS__) )
I posted the following Microsoft support issue:
The following program gives compilation error because the precompiler expands
__VA_ARGS__
incorrectly:#include <stdio.h> #define A2(a1, a2) ((a1)+(a2)) #define A_VA(...) A2(__VA_ARGS__) int main(int argc, char *argv[]) { printf("%d\n", A_VA(1, 2)); return 0; }
The preprocessor expands the printf to: printf("%d\n", ((1, 2)+()));
instead of printf("%d\n", ((1)+(2)));
I received the following unsatisfying answer from a Microsoft compiler team developer:
Hi: The Visual C++ compiler is behaving correctly in this case. If you combine the rule that tokens that match the '...' at the inital macro invocation are combined to form a single entity (16.3/p12) with the rule that sub-macros are expanded before argument replacement (16.3.1/p1) then in this case the compiler believes that A2 is invoked with a single argument: hence the error message.
What version of MSVC are you using? You will need Visual C++ 2010.
__VA_ARGS__
was first introduced by C99. MSVC never attempted to support C99, so the support was not added.
Now, however, __VA_ARGS__
is included in the new C++ standard, C++2011 (previously known as C++0x), which Microsoft apparently plans to support, so it has been supported in recent versions of MSVC.
BTW, you will need to use a .cpp
suffix to your source file to get this support. MSVC hasn't updated its C frontend for a long time.
来源:https://stackoverflow.com/questions/5134523/msvc-doesnt-expand-va-args-correctly