C++ 为什么##aka token pasting操作符在C和C+中不适用于注释+;?

C++ 为什么##aka token pasting操作符在C和C+中不适用于注释+;?,c++,c,concatenation,token,c-preprocessor,C++,C,Concatenation,Token,C Preprocessor,为什么会出现以下错误 #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 concatenat

为什么会出现以下错误

#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;
}
#包括
#定义连接(t1,t2)t1##t2//连接令牌1和令牌2
int main()
{
int-myVar=22;
对于C++,std::cout:

##
必须生成有效的预处理令牌

/
不被视为预处理标记。相反,注释(包括
/
引言)被视为空白,请参见C++17标准(最终草案)的第页

如果
##
未生成有效的预处理令牌,如此处所示,则程序具有未定义的行为。请参阅。这意味着编译器甚至不需要用错误消息告诉您出错


在预处理器指令(例如宏定义和替换)执行之前,所有注释都从源文件中删除,因此即使生成了//令牌,它也不会被替换,将是一个语法错误。参见

< P>此答案是C,它类似于C++。 该示例与中的示例完全相同:

您看到的错误是:

错误:粘贴“/”和“/”不提供有效的预处理令牌

因此,
##
的结果需要预处理标记。简而言之,a是标识符、预处理数字、字符串文本、标点符号和其他。(另请参阅)。生成的
/
字符串不是预处理令牌,因此此处
##
的结果将不是预处理令牌。状态为如果
##
的结果不是有效的预处理令牌,则行为未定义。在这种情况下,您使用的编译器会选择发出错误。它的工作方式与以下方式不同:不工作:

concatenate(:, b) // error, `:b` is not a preprocessing token
concatenate(%, b) // error, `%b` is not a preprocessing token
// etc.
例如,从另一个方面来说,例如
%=
是a。以下是确定的:

concatenate(%, =)
concatenate(/, =)
concatenate(a /, = b)
concatenate(<, :)
连接(%,=)
连接(/,=)
连接(a/,=b)

连接(这是否回答了您的问题?编译器会删除注释,例如
/
/*…*/
,因此将其发送到宏中不会被解释为这样。非常好的解释,+1!但是,它给我提出了另一个问题:如果标记粘贴对于正向斜杠是非法的,为什么我会看到
#如果0#定义DbgPrint/###/#else…
?如果允许0
任何内容,我无法解释为什么您在
#内部看到了某些内容。LOL我的字面意思不是“为什么我看到了这个?”,而是“这是怎么可能的,它意味着什么?”。我知道,
#如果0…
意味着代码永远不可能被处理,我猜正在讨论的开发人员正在创建一个易于注释的代码块用于测试/调试,但我的问题实际上归结为:令牌粘贴部分如何允许它工作?如果你不知道,那就足够了。很抱歉打扰你:-)我不明白。不,不明白。这个答案解释了为什么宏不可能成为注释(最后一段)。另外##要求参数是宏参数。请发布一个。
concatenate(%, =)
concatenate(/, =)
concatenate(a /, = b)
concatenate(<, :)