Visual Studio and .NET Framework Home
Variadic Macro Replacement
as Won't Fix
11/5/2008 12:31:09 AM
User(s) can reproduce this bug
When replacing the __VA_ARGS__ parameter in a variadic macro, the variable arguments, when replaced in the replacement list, are considered as a single token, instead of multiple.
The C/C++ standard defines these steps when replacing variadic macros:
1. Determine the variable arguments.
2. Replace __VA_ARGS__ in the macro's replacement list with the tokens in the variable arguments.
3. Rescan the resulting token list, replacing macros (with the usual restriction of not recursively replacing macros).
However, when you try to recompile the programme below, errors occur. I've checked the same programme with GNU's compiler, and it compiles (and executes) as expected.
Visual Studio 2005 SP1
Operating System Language
Steps to Reproduce
Compile the programme:
using namespace std;
#define FOO(...) BAR(__VA_ARGS__)
#define BAR(a, b) a << b
cout << FOO(1, 2) << endl;
main.cpp(9) : warning C4003: not enough actual parameters for macro 'BAR'
main.cpp(9) : error C2059: syntax error : '<<'
If one looks at the preprocessor output, one gets:
cout << 1, 2 << << endl;
(which explains the second error)
Programme should compile nicely, and print `12' upon execution.
Indeed, by following the steps described in the standard:
1. When scanning FOO(1, 2), the variable arguments consist of the token list: 1 , 2
2. Replacing __VA_ARGS__ in the replacement list yields the list: BAR(1, 2)
3. Rescanning the list, BAR should be expanded with 1 as the token list associated with a and 2 the token list associated with b. This expansion results in: 1 << 2
Thus the preprocessor generates the line:
cout << 1 << 2 << endl;
Which, upon execution, should output `12'.
TAP Code (if applicable)
You can indicate your satisfaction with how Microsoft handled this issue by completing this quick
3 question survey
to post a comment.
Please enter a comment.
on 8/19/2010 at 4:29 PM
I think it is horrendous that Microsoft will not fix an obvious bug in their own implementation of an upcoming C++0x feature and are determined to propagate their own erroneous implementation to the C++ programming world. Everybody responsible for that on the C++ programming team at Microsoft should be ashamed of this decision.
on 8/25/2009 at 10:10 AM
Section 220.127.116.11 in the C99 standard requires to expand __VA_ARGS__ into multiple tokens.
"An identifier __VA_ARGS_ _ that occurs in the replacement list shall be treated as if it were a parameter, and the variable arguments shall form the preprocessing tokens used to replace it".
on 7/1/2009 at 12:19 PM
Any chance this will ever get fixed? VC has never properly supported Variadic Macros and its been in the C standard for 10 years now and claimed to be "supported" in VC for 4 years.
on 11/11/2008 at 3:27 PM
Hi: I can confirm that this is a bug with Visual C++. Unfortunately it does not meet the triage bar for the current release of Visual C++ - but we will keep the issue in our database and we will look at it again during the development phase of a future release of Visual C++.
Visual C++ Compiler Team
on 11/6/2008 at 12:21 AM
Well, in that case, this is a bug with Visual C++'s documentation :) .
Since I don't have access to the ISO/IEC 14882:2003 standard, I'm going to take your word for it and admit my mistake. Thank you for your correction!
On a personal level, this peculiar behaviour is unintuitive, and I hope it'll be changed.
Pavel Minaev [MSFT]
on 11/6/2008 at 12:01 AM
There is no paragraph 12 in section 16.3, nor paragraph 2 in section 16.3.1, in ISO C++ 2003 standard (ISO/IEC 14882:2003). They are present in the working draft for the upcoming C++0x, but it is obviously not a standard yet :) so VC++ not following it is most certainly not a bug. I agree it would be a useful suggestion, though.
VC++ team has a blog on the new C++0x stuff in the upcoming VC10, here:
They are also answering requests on whether particular features of C++0x are going to be implemented in VC10 or not, in the comments (they've already said they aren't going to have a full implementation in the next version). You might get a quicker answer there.
on 11/5/2008 at 9:18 PM
In reply to int19h:
> There is no such thing as a "C/C++ standard" - those are separate.
Indeed, but the part defining macro preprocessor directives is identical for both standards, it's more or less copy/paste.
> In addition, there are no variadic macro arguments in the C++ standard (they are a C99 feature).
There are. In the C++ standard, see:
Section 16.3, paragraphs 5, 10 and 12, and section 16.3.1, paragraph 2. They also appear in the example on section 16.3.5, paragraph 10.
In the C standard, simply replace ``16'' by ``6.10'' in the above citations, and the example is in paragraph 9.
on 11/5/2008 at 6:07 PM
Thanks for your feedback.
We are escalating this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue.
Visual Studio Product Team
Pavel Minaev [MSFT]
on 11/5/2008 at 4:12 AM
There is no such thing as a "C/C++ standard" - those are separate. In addition, there are no variadic macro arguments in the C++ standard (they are a C99 feature). g++ supports it for C++ compilation as an extension.
to post a workaround.
Please enter a workaround.
on 11/20/2010 at 2:47 PM
#define FOO(...) BAR_((__VA_ARGS__))
#define BAR_(tuple) BAR tuple
#define BAR(a, b) a << b
At least this works in Visual Studio 2008 SP1, and I would expect it to work in Visual Studio 2005 also (since this is when MS added "support" for variadic macros).
© 2014 Microsoft