195

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

文件末尾没有换行符

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

4

11 回答 11

225

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


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

通过 James 的帖子来自 C++11 标准:

如果源文件不为空且不以换行符结尾,或者在任何此类拼接发生之前以换行符结尾且紧接在反斜杠字符之前,则应将其视为附加的 new-行字符被附加到文件中(C++11 §2.2/1)。

于 2008-09-16T13:49:29.917 回答
47

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

如果源文件不为空且不以换行符结尾,或者在任何此类拼接发生之前以换行符结尾且紧接在反斜杠字符之前,则应将其视为附加的 new-行字符被附加到文件中(C++11 §2.2/1)。

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

于 2011-11-17T18:30:36.033 回答
28

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

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

于 2008-09-16T13:52:09.600 回答
16

“听话”的答案是“因为 C++03 标准说不以换行符结尾的程序的行为是未定义的”(释义)。

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

于 2008-09-16T13:46:30.503 回答
6

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

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

于 2008-09-16T13:40:39.207 回答
5

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

于 2008-09-16T13:47:45.070 回答
3

当然,实际上每个编译器都会在#include 之后添加一个新行。谢天谢地。– @mxcl

不是特定的 C/C++ 而是 C 方言:使用GL_ARB_shading_language_include扩展时,OS X 上的 glsl 编译器会警告您不要缺少换行符。因此,您可以编写一个MyHeader.h带有标题保护的文件,该文件以结尾,#endif // __MY_HEADER_H__并且您肯定丢失该行#include "MyHeader.h"

于 2014-12-23T16:47:51.763 回答
2

我正在使用无 c 的 IDE 5.0 版,在我的“c++”或“c”语言的程序中,我遇到了同样的问题。就在程序的最后,即程序的最后一行(在函数大括号之后,它可能是main 或任何功能),按回车-行号。将增加1。然后执行相同的程序,它将运行没有错误。

于 2012-12-11T09:47:33.483 回答
2

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

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

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

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

于 2015-08-06T08:43:25.350 回答
0

此警告还可能有助于表明文件可能已被截断。确实,编译器无论如何都会抛出编译器错误——尤其是在函数中间时——或者可能是链接器错误,但这些可能更神秘,并且不能保证会发生。

当然,如果文件在换行后立即被截断,也不能保证这个警告,但它仍然可以捕捉到其他错误可能遗漏的一些情况,并为问题提供更强有力的提示。

于 2012-01-07T16:19:58.593 回答
-1

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

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

不过,除此之外,您应该使用#include <iostream>而不是<iostream.h>. 然后在using std::cout;它后面放一个。

于 2011-07-21T09:07:00.153 回答