考虑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编译
哪个是对的?
考虑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编译
哪个是对的?
2条答案
按热度按时间ne5o7dgx1#
从C11开始,
"hello world"s
是一个匹配 user-defined-string-literal 语法生成的预处理标记。宏在预处理标记级别上进行替换。由于没有
s
预处理标记,因此不能对宏进行任何替换。因此,您的代码在C14或更高版本中是格式良好的。选择
std::operator""s
。在C11中没有std::operator""s
。然而,在C11之前,当引入用户定义的文字时,
"hello world"s
将是两个预处理标记"hello"
和s
,因此后者将被您的宏替换。这甚至在[diff.cpp03.lex]/2中被明确地提到为与C++11向后不兼容的更改。
jv4diomz2#
GCC错了。
像
"hello world"s
这样的用户定义字符串文字是一个预处理标记,而不是两个预处理标记"hello world"
和s
。预处理器不应该替换预处理令牌的一部分。