为什么这是一个end-recursive可变宏? [英] Why is this an end-recursive variadic macro?
问题描述
以下构造在VisualStudio 2013中编译。我刚刚创建了一个新的consoleApplication项目,只更改了主要的.cpp文件,因此您可以粘贴并试用它。它显然是创建一个结束递归的可变宏。
The following construct compiles in VisualStudio 2013. I just made a new consoleApplication project and only changed the main .cpp, so you can just paste this and try it out. What it apparently does is create an end-recursive variadic macro.
#include "stdafx.h"
#include <iostream>
using namespace std;
#define DEFINE_ENUM_VALUE(name, i) name = i,
#define _DEFINE_ENUM_VALUES(i, name, ...) DEFINE_ENUM_VALUE(name, i+1)
#define DEFINE_ENUM_VALUES(enum_name, name, ...) enum class enum_name{ \
DEFINE_ENUM_VALUE(name, 0) _DEFINE_ENUM_VALUES(1, __VA_ARGS__) \
};
DEFINE_ENUM_VALUES(names, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9)
int _tmain(int argc, _TCHAR* argv[])
{
cout << (int)names::_0 << ' ';
cout << (int)names::_1 << ' ';
cout << (int)names::_2 << ' ';
cout << (int)names::_3 << ' ';
cout << (int)names::_4 << ' ';
cout << (int)names::_5 << ' ';
cout << (int)names::_6 << ' ';
cout << (int)names::_7 << ' ';
cout << (int)names::_8 << ' ';
cout << (int)names::_9 << ' ';
return 0;
}
这不仅编译,而且几乎可以想象。输出为:
This not only compiles, but also works only nearly as one may imagine. The output is this:
0 1 2 3 4 5 6 7 8 2
这是不是错字,值 names :: _ 9
是2.这是这样定义的每个枚举的情况,最后一个值总是2.我测试这个与3-15参数的整个范围。
This is not a typo, the value of names::_9
is 2. And this is the case for every enum defined like this, the last value is always 2. I tested this with a whole range from 3-15 arguments.
有人知道这里发生了什么吗?
Does anyone have an idea what's going on here?
为什么MSVC预处理器多次扩展 DEFINE_ENUM_VALUE
?为什么,如果它是想要的行为(我怀疑),它是否使最后的值2?
Why is the MSVC pre-processor expanding DEFINE_ENUM_VALUE
multiple times? And why, if it's intended behaviour (which I doubt), does it make the last value 2?
我也测试了它与ideone,预期,注意 names :: _ 1
之后的所有内容不是 names
的一部分。
I also tested it with ideone, and it did fail to compile as expected, noting that everything after names::_1
wasn't part of names
.
推荐答案
即使这是无谓的,因为克里斯注意到这已被标记为不会修复,并且还影响MSVC Update4(在编写此文档时)
Even if this is nonsense, as chris noted this has been marked "won't fix" and also affects MSVC Update4 (at the time of writing this)
Hi:我可以确认这是Visual C ++的错误。不幸的是,它不符合当前版本的Visual C ++的分类栏 - 但我们将保留在我们的数据库中的问题,我们将在Visual C ++的未来版本的开发阶段再次查看。
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++.
Jonathan Caves
Visual C ++编译器团队
Jonathan Caves Visual C++ Compiler Team
发布相关摘录,在 _DEFINE_ENUM_VALUES
宏中替换时,code> __ VA_ARG __ 参数被视为单个标记而不是多个,因此输出
to post the relevant excerpts, the __VA_ARG__
parameter when replaced in the _DEFINE_ENUM_VALUES
macro, is considered as a single token instead of multiple ones thus outputting
enum class names{ _0 = 0, _1, _2, _3, _4, _5, _6, _7, _8, _9 = 1+1, };
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this is a single token
for MSVC
而不是
enum class names{ _0 = 0, _1 = 1 +1, };
这样做可能不太明显,例如
this might not be obvious when doing something like
#define printf_macro(format_string, ...) printf(format_string, __VA_ARGS__)
但在上述示例中变得明显。
but becomes evident in the example above.
这篇关于为什么这是一个end-recursive可变宏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!