【问题标题】:Using macro with string fails on VC 2015在 VC 2015 上使用带有字符串的宏失败
【发布时间】:2015-10-22 16:44:27
【问题描述】:

为什么编译失败?

char programDate[] = "("__DATE__")";

但这编译得很好(见空格):

char programDate[] = "(" __DATE__")";

我知道 VC2015 现在支持文字运算符。但这不应该处于编译阶段吗? __DATE__ 应该已经被预处理器处理过了。这是怎么回事?

我想到了 Unicode/非 Unicode 构建的一些混合匹配问题 - 但它没有帮助。这不仅仅是预定义宏的问题,还有用户定义的问题:

#define MACRO "abc"
char data[] = "("MACRO")";

编辑:

Error C3688 invalid literal suffix '__DATE__'; literal operator or literal operator template 'operator ""__DATE__' not found

【问题讨论】:

  • 我认为您在评论中可能对用户定义的文字有所了解。通常,C++ 解析器是maximum munch,对于每个令牌,它们会吞下尽可能多的字符,直到它不再是有效的令牌。
  • 你可以写编译错误。

标签: c++ macros visual-studio-2015 user-defined-literals


【解决方案1】:

自 C++11 起,用户定义的文字存在并且是预处理的一部分。语法是:

preprocessing-token:
    user-defined-string-literal
    // other stuff...

user-defined-string-literal:
    string_literal ud-suffix

ud-suffix:
    identifier

所以 "("__DATE__ 匹配 preprocessing-token,但 "(" __DATE__ 不匹配(即两个单独的预处理令牌)。

宏替换发生在标记化之后。由于在您的第一个示例中没有令牌 __DATE__,因此没有替换。

【讨论】:

  • 如果有人没有意识到 C++ 预处理器与 C 预处理器不同......现在你知道了 :)
  • 在 VS 2015 中使用 C++11 用户定义的文字,您还可能遇到 L"Hello, "L"World" 以前可以工作但失败并出现相同错误的问题,因为它尝试使用第二个 L 作为UDF。你用空格修复它:L"Hello, " L"World"
  • 谢天谢地,现在可以连接不匹配的字符串 - 所以不需要第二个L! (stackoverflow.com/questions/31809141/…)
  • 是否因为与后缀字符串运算符 "Hello world"s 冲突而更改? en.cppreference.com/w/cpp/string/basic_string/operator%22%22s
猜你喜欢
  • 1970-01-01
  • 2016-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多