【发布时间】:2017-03-26 12:12:42
【问题描述】:
我们应该如何使用 C++ 标准来解释下面的宏定义?请注意,主要问题是 AA 的替换列表包含嵌入式逗号 (for, S)
#define AA for, S //<---note the embedded comma
#define VALUE_TO_STRING(x) ^x!
#define VALUE(x) VALUE_TO_STRING(x)
int _tmain(int argc, _TCHAR* argv[])
{
VALUE(AA)
return 0;
}
我已经使用 VC++2010 进行了测试,上面的最终结果如下所示,没有任何错误,但我在解释使用 C++03 得出结果所采取的步骤时遇到问题(或 C++11)标准:
int wmain(int argc, _TCHAR* argv[])
{
^for, S!
return 0;
}
我已经使用 VC++2010 进行了一些逐步测试。首先我注释掉第二个宏,看看第一步发生了什么:
#define AA for, S
//#define VALUE_TO_STRING(x) ^x!
#define VALUE(x) VALUE_TO_STRING(x)
宏替换很简单,生成的序列看起来像另一个具有两个参数的类似函数的宏:
int wmain(int argc, _TCHAR* argv[])
{
VALUE_TO_STRING(for, S)
return 0;
}
根据 [cpp.rescan],下一步是重新扫描它以获取更多宏名称。这里的问题是这个新宏是否应该被解释为具有 2 个参数或 1 个参数“for, S”的类函数宏。
通常的解释是认为 VALUE_TO_STRING() 给出了 2 个无效的参数,因此会导致预处理器错误。但是 VC++ 怎么会得出一个没有任何错误的结果呢?显然,VC++ 采取的第二步是将for, S 视为一个没有意义且未由 C++ 标准定义的单个参数。
【问题讨论】:
-
为什么要投反对票???
-
我没有投反对票。我刚刚对这个问题投了赞成票,在我看来这个问题很难,但很清楚也很有用。
-
VC++ 没有符合标准的预处理器。
标签: c++ c-preprocessor language-lawyer