c++ - 为什么成对的注释不能放在 C++ 中的字符串中?
问题描述
通常里面的任何东西/*
都*/
被视为评论。
但是该语句
std::cout << "not-a-comment /* comment */";
打印not-a-comment /* comment */
而不是not-a-comment
.
为什么会这样?c++ 中还有其他不能使用注释的地方吗?
解决方案
这是最大咀嚼原则的结果。这是 C++ 语言遵循的词法规则。处理源文件时,翻译分为(逻辑)阶段。在第 3 阶段,我们得到预处理令牌:
[lex.阶段]
1.3源文件被分解为预处理标记和空白字符序列(包括注释)。源文件不应以部分预处理标记或部分注释结尾。每个注释被一个空格字符替换。保留换行符。
将评论转换为空白 pp-tokens 是在同一阶段完成的。现在字符串文字是一个 pp-token:
[lex.pptoken]
preprocessing-token: header-name identifier pp-number character-literal user-defined-character-literal string-literal user-defined-string-literal preprocessing-op-or-punc each non-white-space character that cannot be one of the above
和其他文字一样。最大咀嚼原则告诉我们:
3如果输入流已被解析为预处理标记,直到给定字符:
- 否则,下一个预处理标记是可以构成预处理标记的最长字符序列,即使这会导致进一步的词法分析失败,除非标头名称仅在 #include 指令中形成。
因此,因为预处理找到了开头"
,它必须继续寻找最长的字符序列,这将构成一个有效的 pp-token(在这种情况下,token 是一个字符串文字)。这个序列在结束时结束"
。这就是为什么它不能停止和处理评论,因为它有义务消耗到右引号。
遵循这些规则,您可以确定预处理器不会将注释作为注释处理的位置。
推荐阅读
- sql-server - COM+ VB6 应用程序:RM_ENLIST_FAILED_TOO_MANY_ENLISTS 错误
- blazor - 检查 Blazor 应用程序是 WebAssembly 还是服务器?
- terraform - terraform 与一个状态文件的协作
- java - 用于 Java 的 ANTLR4。如何在词法分析中显示错误
- html - 角度错误 ICU 消息无效。失踪
- matlab - 如何绘制分段线性函数?
- javascript - Axios 在 React 应用程序中请求响应 401,但在 Postman 中工作?
- ios - React Native Native Module - 将 JSON 属性传递给 Swift UIView
- sql - 在海量红移表中搜索重复值的最有效方法
- sql - 从返回几年的查询中获取最大月份