c++ 预处理器是否在`operator”"_name`中定义替换

vcirk6k6  于 2023-08-09  发布在  其他
关注(0)|答案(2)|浏览(151)

考虑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编译
哪个是对的?

ne5o7dgx

ne5o7dgx1#

从C11开始,"hello world"s是一个匹配 user-defined-string-literal 语法生成的预处理标记。
宏在预处理标记级别上进行替换。由于没有s预处理标记,因此不能对宏进行任何替换。
因此,您的代码在C
14或更高版本中是格式良好的。选择std::operator""s。在C11中没有std::operator""s
然而,在C
11之前,当引入用户定义的文字时,"hello world"s将是两个预处理标记"hello"s,因此后者将被您的宏替换。
这甚至在[diff.cpp03.lex]/2中被明确地提到为与C++11向后不兼容的更改。

jv4diomz

jv4diomz2#

GCC错了。
"hello world"s这样的用户定义字符串文字是一个预处理标记,而不是两个预处理标记"hello world"s。预处理器不应该替换预处理令牌的一部分。

相关问题