atest.c
#define COMMENT /##/
int main()
{
...
COMMENT int atest;
...
}
错误消息:
atest.c:16:1: error: pasting "/" and "/" does not give a valid preprocessing token
atest.c: In function 'main':
atest.c:16: error: expected expression before '/' token
虽然Microsoft C编译器对COMMENT宏感到满意。 here的提示也不起作用。
有人可以为此提供解决方案或解释吗?感谢。
答案 0 :(得分:8)
使用标记粘贴运算符##
时,组合两个操作数的结果必须是有效的预处理程序标记。
//
不是有效的预处理令牌。删除注释后会发生预处理,因此无法在预处理阶段添加注释。
答案 1 :(得分:4)
由于注释处理是在之前的宏之前完成的,因此编译器无法识别宏生成的注释。引用Ben Combee对您引用的文章的回应:
我刚刚阅读了2001年1月发行的C / C ++技巧#5 CUJ。提示的内容(做一个扩展为一个宏的宏) 评论)非常熟悉,因为我看到部署了类似的方法 在Microsoft的一个头文件中。但是,小费非常好 不正确。
编写器使用标记粘贴来构造注释开始序列。 但是,根据C和C ++标准,这是无效的。在 ISO C(1999)第5.1.1.2节,标题为“翻译阶段”,评论 处理发生在阶段3中,其中预处理器识别令牌 和空格,用空格替换注释。宏 然后在阶段4中完成处理,并且该阶段是其中的阶段 这些新的评论开始序列将被引入。没有 #4之后的后续阶段,其中评论将被识别,所以 最终,符合标准的编译器将拒绝由于的程序文本 非法令牌 - '//'。 1998 C ++标准中有类似的语言 第2.1节,“翻译阶段[lex.phases]。”
一些编译器将阶段的顺序和处理充分混合到 允许这个宏工作,微软的Visual C ++ 6.0值得注意 它的人气。其他的,如Metrowerks CodeWarrior C / C ++ 编译器(我作为编译器工作了两年多) 在我目前的工作之前的工程师)遵循标准和意志 拒绝提示中显示的用法。
谢谢,
Ben Combee 首席软件架构师 Veriprise Wireless http://www.veriprise.com
因此,期刊后面跟着这个通知:
因此,我们要提醒读者,此提示不可移植,可能不应在生产代码中使用。
答案 2 :(得分:2)
对不起,我对如何做到这一点没有答案。
您可以使用命令cpp(c prepocessor)预处理代码并查看发生的情况。 通过cpp运行提供的代码提供以下内容:
int main()
{
a.c:5:1: error: pasting "/" and "/" does not give a valid preprocessing token
/ / int atest;
}
尝试
#define COMMENT /
#define SLASH(x) x/
SLASH(COMMENT)
结果
/ /
然而尝试
#define TEST(y) y/
TEST(hello)
结果
hello/
通常会删除诸如//之类的注释并替换为单个“注释令牌”,此步骤在预处理之前完成(当#指令发生时),因此即使你可以在那里得到你的评论,我也怀疑它永远被认可(AFAIK标准不保证)。
对不起,我无法提供更多帮助。