“文件末尾没有换行符”编译器警告

问题描述 投票:178回答:11

在某些C ++编译器中出现以下警告的原因是什么?

文件末尾没有换行符

为什么我应该在源/头文件的末尾有一个空行?

c++ compiler-construction warnings c-preprocessor
11个回答
208
投票

想想如果没有新行可能会出现的一些问题。根据ANSI标准,开头文件的#include将文件完全按原样插入到文件的前面,而不是在文件内容之后的#include <foo.h>之后插入新行。因此,如果您在解析器的末尾包含一个没有换行符的文件,它将被视为foo.h的最后一行与foo.cpp的第一行在同一行。如果foo.h的最后一行是没有换行的注释怎么办?现在foo.cpp的第一行被注释掉了。这些只是可能出现的问题类型的几个例子。


只是想将任何感兴趣的人指向詹姆斯的答案。虽然上述答案对于C仍然是正确的,但新的C ++标准(C ++ 11)已经更改,因此如果使用C ++和符合C ++ 11的编译器,则不应再发出此警告。

从C ++ 11标准到James'帖子:

一个非空的并且不以换行符结尾的源文件,或者在任何此类拼接发生之前以反斜杠字符开头的新行字符结尾的源文件,应该被处理,就像另一个新文件一样 - 行字符被附加到文件中(C ++11§2.2/ 1)。


0
投票

此警告也可能有助于指示文件可能以某种方式被截断。确实,编译器可能会抛出编译器错误 - 特别是如果它位于函数中间 - 或者可能是链接器错误,但这些可能更加神秘,并且不能保证会发生。

当然,如果文件在换行符后立即被截断,也不能保证此警告,但它仍然可以捕获其他错误可能会遗漏的情况,并提供更强的问题提示。


-2
投票

那不是错误。这只是一个警告。

在编辑器中打开文件,转到文件的最后一行,然后按Enter键在文件末尾添加一个空行。

虽然,除此之外,你应该使用#include <iostream>而不是<iostream.h>。然后在它之后放入using std::cout;


42
投票

在C ++ 11中删除了每个源文件以非转义换行符结尾的要求。该规范现在为:

一个非空的并且不以换行符结尾的源文件,或者在任何此类拼接发生之前以反斜杠字符开头的新行字符结尾的源文件,应该被处理,就像另一个新文件一样 - 行字符被附加到文件中(C ++11§2.2/ 1)。

符合标准的编译器不应再发出此警告(至少在C ++ 11模式下编译时,如果编译器具有针对语言规范的不同修订版的模式)。


24
投票

C ++ 03标准[2.1.1.2]声明:

...如果非空的源文件不以换行符结尾,或者在任何此类拼接发生之前以反斜杠字符开头的新行字符结尾,则行为未定义。


15
投票

“服从”的答案是“因为C ++ 03标准说未以新行结尾的程序的行为未定义”(转述)。

奇怪的答案在这里:http://gcc.gnu.org/ml/gcc/2001-07/msg01120.html


6
投票

它不是指空行,而是最后一行(可以包含其中的内容)是否以换行符终止。

大多数文本编辑器会在文件的最后一行末尾添加换行符,因此如果最后一行没有换行符,则存在文件被截断的风险。但是,有充分的理由说明为什么您可能不需要换行符,因此它只是一个警告,而不是错误。


5
投票

#include将用文件的文字内容替换它的行。如果文件没有以换行符结尾,则包含引入它的#include的行将与下一行合并。


2
投票

我正在使用无c的IDE版本5.0,在我的程序中,无论是'c ++'还是'c'语言我都遇到了同样的问题。只是在程序的最后,即程序的最后一行(在功能的大括号之后它可能是主要或任何功能),按输入行号。将增加1.然后执行相同的程序,它将运行没有错误。


2
投票

当然,在实践中,每个编译器都会在#include之后添加一个新行。值得庆幸的。 - @mxcl

不是特定的C / C ++而是C语言:当使用GL_ARB_shading_language_include扩展时,OS X上的glsl编译器警告你不要错过换行符。所以你可以写一个MyHeader.h文件,其中有一个以#endif // __MY_HEADER_H__结尾的标题后卫,你肯定会在#include "MyHeader.h"之后输掉这一行。


2
投票

因为如果文件不以换行结束,则C / C ++版本之间的行为会有所不同。特别令人讨厌的是旧的C ++ - 版本,fx在C ++ 03标准中说(翻译阶段):

如果非空源文件不以换行符结尾,或以紧跟在反斜杠字符前面的换行符结尾,则行为未定义。

未定义的行为是不好的:符合标准的编译器可以在这里做或多或少的事情(插入恶意代码或其他) - 显然是警告的原因。

虽然在C ++ 11中情况更好,但最好避免在早期版本中未定义行为的情况。 C ++ 03规范比C99更糟糕,它完全禁止这些文件(然后定义行为)。

© www.soinside.com 2019 - 2024. All rights reserved.