通常,如果代码中存在*/
(阻止评论结束)而没有/*
(阻止评论开放),编译器产生错误。
但是,为什么编译器 NOT 会在以下情况下产生错误?
#include <stdio.h>
int main(void)
{
#ifdef abcd
printf("what ever it is");
#endif */ --> the problem with this stray '*/' after #endif
return 0;
}
答案 0 :(得分:3)
我刚刚用gcc 4.6.x编译了你提供的代码而没有任何标志,并得到了警告
warning: extra tokens at end of #endif directive [enabled by default]
所以预处理器首先删除所有注释,然后跳过#endif行的所有数据。所以我不知道它是一个错误还是一个功能,但我得到了关于它的警告,所以开发人员知道这个问题。
答案 1 :(得分:2)
受过教育的猜测:这绝对是预处理器中的一个错误,它的作用是忽略#endif
之后的所有内容,无论如何都无法跟踪。
答案 2 :(得分:0)
如果我收到你的问题:
/*
#ifdef abcd
printf("what ever it is");
#endif */
您从头开始删除了“/ *”,代码无法编译?
这很好,因为代码不应该编译。如果没有开头,你的评论会更接近。
您可以做的是将“ /”替换为“// /”:
/*
#ifdef abcd
printf("what ever it is");
#endif //*/
这样你可以毫无问题地从头开始删除“/ *”。
答案 3 :(得分:0)
#endif */
这是块评论的结束,块评论开放在哪里?
/*
答案 4 :(得分:0)
首先,由于*/
不是评论的一部分,因此在C 2011(n1570)5.1.1.2 1 3中描述的翻译阶段3中将其忽略。字符只是不变地传递。
因此,在阶段4(执行预处理程序指令)中,编译器会看到#endif */
。根据C 2011(n1570)6.10 1,#endif
指令的正确语法是:
# endif new-line
也就是说,它由三个预处理令牌#
,endif
和一个换行符组成,在令牌之间允许使用空格和制表符。所以#endif */
不是正确的语法。
如果源违反语法规则,5.1.1.3要求符合要求的实现生成诊断消息。因此,如果编译器在这种情况下不产生警告或错误消息,则它不符合。
某些编译器默认以不符合C标准的模式运行。您的编译器可能有开关来更改它,例如GCC的-std=c99
开关。如果您的编译器在符合模式下没有发出警告或错误消息,那么这就是一个错误。