msc*_*msc 5 c gcc newline clang
从C11 5.1.1.2 翻译阶段:
第 2 段:
[...]非空的源文件应以换行符结尾,在发生任何此类拼接之前,换行符前面不应紧接反斜杠字符。
这意味着每个源文件都必须以换行符结尾。
例子:
#include <stdio.h>
int main()
{
printf("Hello world\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
上面的示例使用命令在 Clang 上编译clang prog.c -Wall -Wextra -std=gnu11 -pedantic。编译器生成以下警告:
prog.c:7:16: warning: no newline at end of file [-Wnewline-eof]
}
^
Run Code Online (Sandbox Code Playgroud)
没关系,因为源文件末尾没有换行符。
我使用gcc prog.c -Wall -Wextra -std=gnu11 -pedantic命令在 GCC 上编译了上述程序。GCC 不会生成任何警告或错误。
那么,为什么 GCC 不生成任何警告或错误呢?
有一个问题,换行符没有很好的标准定义,因为不同的系统有不同的换行符约定。但你是对的......如果标准规定编译器在这种情况下必须发出警告而 gcc 不发出警告,则应将其作为不合规问题归档。
但我同意@supercat的答案,从某种意义上说,可以假设没有结尾的文件\n可以安全地解释为正确分隔的文本文件,末尾没有行结尾...因为\n可以解释为一行分隔符,而不是以 1 结尾的行。如果此解释有效,则空文件将被解析为一个空行文件,编译器解析它不会出现问题,并且在这种情况下不应发出警告。这同样适用于任何没有final的文件\n,并且以a结尾的文件\n应该被解释为一个n + 1行文件,带有一个额外的空行(恐怕这对里面的C代码的含义没有任何影响) )
如果您去 gcc 项目投诉,您可能会得到这样的答复,所以要谨慎,但不要犹豫,去做吧。
顺便说一句,您是否尝试向编译器提供最后一个\\字符(不带\n字符),允许编译器插入最后的换行符来模拟正确定义的文件,但预处理器必须以特殊形式处理,以防\\字符接下来是一个新行。在这种情况下,编译器应该发出一些东西,因为您无法继续超过文件的最后一行。Clang 没有说什么,以防最后一行以 a 终止\\(这是不合格的)让我们看看 gcc 会做什么......(抱歉,我现在无法访问 gcc)