为什么 ## aka 令牌粘贴运算符不适用于 C 和 C++ 中的注释?
Why does the ## aka token-pasting operator not work for comments in C and C++?
为什么会出现以下错误?
#include <iostream>
#define concatenate(t1, t2) t1 ## t2 // Concatenate token1 and token2
int main()
{
int myVar = 22;
std::cout << concatenate(my, Var); // Compiles fine and outputs the value of myVar
concatenate(/, /) So I thought that this would be a comment but this is a compile-time error
// error: pasting "/" and "/" does not give a valid preprocessing token
return 0;
}
我以为concatenate(/, /)
会告诉预处理器用//
替换它,然后随着它的进一步解析,整行将被解释为注释。
在这种情况下,实际发生了什么?
这个答案是针对C的,在C++中是相似的。
该示例与 C11 标准 6.4.9p3 中的示例完全相同:
#define glue(x,y) x##y
glue(/,/) k(); // syntax error, not comment
您看到的错误:
错误:粘贴"/"和"/"未提供有效的预处理令牌
由此产生的##
结果需要预处理令牌。简而言之,预处理标记是标识符、预处理数字、字符串文本、标点符号等。(另请参阅关于标记化的 gcc 文档(。生成的//
字符串不是预处理令牌,因此此处##
的结果不是预处理令牌。C 标准 6.10.3.3p3 指出,如果##
的结果"不是有效的预处理令牌,则行为未定义"。在这种情况下,您使用的编译器会选择发出错误。它的工作方式与以下方法不起作用的方式不同:
concatenate(:, b) // error, `:b` is not a preprocessing token
concatenate(%, b) // error, `%b` is not a preprocessing token
// etc.
例如,也许从另一边,例如%=
是一个有效的令牌,一个标点符号。以下都可以:
concatenate(%, =)
concatenate(/, =)
concatenate(a /, = b)
concatenate(<, :)
无论如何,即使//
是有效的预处理,注释也会在翻译阶段 3 中替换为单个空格,而预处理器在删除注释后在翻译阶段 4 中执行,请参阅 C11 翻译阶段。因此,即使它会导致//
令牌,它也将是无效的,因为它在 C 中没有任何意义(注释除外(。
对于C++:
##
必须生成有效的预处理令牌。
//
不被视为预处理令牌。相反,注释,包括//
介绍人,被认为是空白的,参见C++17标准(最终草案(的[lex.token]/1。
如果##
未生成有效的预处理令牌(如此处(,则程序具有未定义的行为。见[cpp.concat]/3。这意味着编译器甚至不需要用错误消息来告知您搞砸了。
在执行预处理器指令(如宏定义和替换(之前,将从源文件中删除所有注释,因此即使可以生成//
令牌,也不会替换它,并且会是语法错误。参见[lex.phases]/1.3-1.4
- Visual Studio 2019:插入多个C++风格的单行注释
- VSCode 中带有 C/C++ 扩展名的多行注释缩进错误
- 如果我注释掉换行符,为什么'string'会成为一个不合格的变量
- 为什么 ## aka 令牌粘贴运算符不适用于 C 和 C++ 中的注释?
- 在 // C++注释中使用 \\ 是否合法?(C++评论中的LaTeX方程)
- 注释一行使代码工作,而没有它,代码不起作用
- 使用 Doxygen 在不同文件中注释函数
- 如何设置叮当格式的注释编译指示,以免触及多行doxygen注释?
- Qt - 带有注释的 JSON
- Visual Studio Community 代码分析的质量与 SAL 注释
- 如何阻止 ReSharper 在 C++ 中格式化多行注释
- C++,在多行代码段中注释
- 使用 Python 和正则表达式提取源代码中的C++注释
- 使用 C++ std::sregex_token_iterator 提取 HTML 注释
- C(嵌入式):注释 FreeRTOS 的 RootTask 时代码大小不会缩小
- 我需要帮助创建一个评分系统,但它一直给我一个错误,注释掉的整数是给我带来麻烦的部分
- 如何确保 C/C++ 代码中不会缺少 doxygen 风格的文档注释?
- 删除被注释掉的代码,而不是实际的赞美
- Cpp检查规则不显示 #define,注释
- Visual Studio 2017 是否有用于创建单行注释的特定键盘组合?