c++ 类对象宏扩展不仅仅是替换?

n3h0vuf2  于 2023-08-09  发布在  其他
关注(0)|答案(1)|浏览(116)

我一直认为object-like macro-expansion只是预处理器的简单替代。但是,下面的代码片段不起作用。我希望它能扩展到第二个例子。但它没有...

#define R "x"

auto main() -> int {

  const char* s = R"y"; // ill-formed raw string literal
  const char* s2 = "x""y"; // a raw string literal followed by a normal string literal

  return 0;
}

字符串
有一个神奇的空间,它只是工作。

const char* s = R "y";


这是什么词法分析吗如果是这样,它发生在哪个翻译阶段?- 谢谢-谢谢

hlswsv35

hlswsv351#

原始字符串字面量是在C11中引入的,以下内容仅适用于C11。在C11之前,你所有的例子都是格式良好的。这是C11故意做出的向后不兼容的更改。
例如,原始字符串文字具有以下形式

R"END(this is a "raw" string literal)END"

字符串
它等价于普通字符串文字"this is a \"raw\" string literal"
END可以是任何任意的,可能是空的,字符序列(不包括一些字符,长度有限)标记文字的结束,在R之前可能有一个编码前缀,如L。在任何情况下,()都不是可选的。它们是字符串字面量语法的一部分。
宏替换发生在翻译阶段4中,其在阶段3中形成预处理标记之后。
原始字符串文字,像任何其他文字一样,是一个单独的预处理标记。
在阶段3预处理期间,通过连续检查输入序列中的字符来逐个形成标记。当开始解析一个新的token时,接下来的字符是R",可选地以一个原始字符串的可能的编码前缀作为前缀,那么该token总是被假设为一个原始字符串字面量,并且根据我上面描述的语法 * 必须 * 有效。如果它不是有效的原始字符串文字,那么程序是病态的。编译器永远不会将R解析为一个单独的标记,后跟一个普通的字符串文字。这是专门为原始字符串文字制定的词法分析规则中的一个例外。
因为这发生在阶段4中的任何宏替换之前,所以#define R "x"根本不相关,而R"y"是一个病态的原始字符串文字,因为它没有语法所需的(),导致阶段3已经失败。
"x""y"中没有原始字符串文字,因为没有R"。这是两个普通的字符串文字"x""y"
R "y"不是病态的,因为这是两个标记R"y"。空格始终分隔标记(字符串/字符文字的引号内除外)。R将在阶段4中被"x"替代,并且没有问题。

相关问题