为什么" #define WC(p)L#p"不在GCC和Clang工作?

时间:2014-07-31 20:29:09

标签: c++ visual-c++ gcc clang

演示程序:

#include <iostream>
using namespace std;

#define WC(p) L#p

int main()
{
    wcout << WC(XXX);
}

它在Visual C ++上运行得非常好,但无法在Linux上的Clang和GCC上进行编译。错误(clang 3.4,Linux):

  • file.cpp:8:11:错误:使用未声明的标识符&#39; L&#39;
  • file.cpp:4:15:注意:从宏&#39; WC&#39;
  • 扩展

为什么会失败?如何使用C定义创建宽字符串字符串?在我的情况下,这种能力会大大减少代码重复。

1 个答案:

答案 0 :(得分:3)

预处理器对一系列令牌进行操作。

在宏WC(p)的定义中,替换列表中有三个令牌:L#p。当然,#是一个运营商,其中&#34; stringizes&#34;以下标记。重要的是L本身就是一个标记。 WC(XXX)上宏替换的结果是两个令牌:L"XXX"

另一方面,宽字符串文字是单个标记。无论宏替换列表的拼写如何,两个单独的标记(其中一个是L而另一个是窄字符串文字), not 构成一个宽字符串文字。它与L "XXX"相同,带有空格。

您需要将两个标记粘贴到一个标记中,以获得宽字符串文字。这表明了以下解决方案:

#define WC(p) L ## #p

修改:但是,正如评论中所指出的,这可能无效,因为该语言无法保证在#之前评估##。我们必须强制预处理器首先将p转换为字符串,然后粘贴标记:

#define CONCAT(x, y) x ## y
#define WC(p) CONCAT(L, #p)

现在WC(XXX)将首先进行宏替换以产生CONCAT(L, "XXX")。然后进一步宏替换产生单个令牌L"XXX"