考虑 Aykhan Hagverdili 提供的以下示例:
#include <string>
using std::operator""s;
#define s foobar
auto s = "hello world"s;
某些编译器会替换
s
并导致编译失败。
有些编译器不会替换 s
。
在此处查看结果:https://godbolt.org/z/jx4nhYczd gcc 失败,clang 编译
哪个是对的?
"hello world"s
是与 用户定义的字符串文字语法生成相匹配的单个预处理标记。
宏在预处理标记级别上进行替代。由于没有
s
预处理标记,因此无法替换您的宏。
因此,您的代码在 C++14 或更高版本中格式良好。选择
std::operator""s
。在 C++11 中没有 std::operator""s
。
但是,在 C++11 引入用户定义文字之前,
"hello world"s
将是两个预处理标记 "hello"
和 s
,因此后一个将被替换为您的宏。
这甚至在 [diff.cpp03.lex]/2 中明确提到为与 C++11 向后不兼容的更改。
GCC 错了。
像
"hello world"s
这样的用户定义字符串文字是一个预处理标记,而不是两个预处理标记 "hello world"
和 s
。预处理器不应替换预处理令牌的一部分。