2

通常,如果代码中存在*/(block comment closing)而没有/*(block comment opening),编译器会产生错误。

但是,为什么编译器在以下情况下不会产生错误?

#include <stdio.h>
int main(void)
{
    #ifdef abcd
    printf("what ever it is");
    #endif */   --> the problem with this stray '*/' after #endif
    return 0;
}
4

5 回答 5

3

我刚刚编译了您使用 gcc 4.6.x 提供的代码,没有任何标志并收到警告

warning: extra tokens at end of #endif directive [enabled by default]

所以预处理器首先删除所有注释,然后跳过#endif 行的所有数据。所以我不知道这是一个错误还是一个功能,但我收到了关于它的警告,所以开发人员知道这个问题。

于 2013-03-28T12:50:28.857 回答
2

有根据的猜测:这严格来说是预处理器中的一个错误,它所做的是忽略 a 之后的所有#endif内容,无论如何都不能跟随任何内容。

于 2013-03-28T12:41:32.670 回答
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开关。如果您的编译器在符合模式下没有发出警告或错误消息,那么这是一个错误。

于 2013-03-28T13:15:56.673 回答
0

如果我收到您的问题:

/*
#ifdef abcd
printf("what ever it is");
#endif */

您从一开始就删除了“/ *”并且代码无法编译?

这很好,因为代码不应该编译。你有一个没有开始的评论。

你可以做的是用“// /”替换“/”:

/*
#ifdef abcd
printf("what ever it is");
#endif //*/

这样您就可以毫无问题地从一开始就删除“/*”。

于 2013-03-28T12:39:19.830 回答
0
#endif */

那是块注释的结尾,块注释在哪里打开?

/*
于 2013-03-28T12:39:44.960 回答