当前位置:首页> 正文

关于C++:”文件末尾无新行”编译器警告“No newline at end of file”

关于C++:”文件末尾无新行”编译器警告“No newline at end of file”

“No newline at end of file” compiler warning

在某些C++编译器中,下面的警告是什么原因?

No newline at end of file

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


想想如果没有换行符可能会出现的一些问题。根据ANSI标准,文件开头的#include插入文件的方式与文件前面的方式完全相同,并且不在文件内容后面的#include 后面插入新行。因此,如果在解析器的末尾包含一个没有换行符的文件,那么它将被视为foo.h的最后一行与foo.cpp的第一行位于同一行。如果foo.h的最后一行是没有新行的注释呢?现在,foo.cpp的第一行被注释掉了。这些仅仅是一些可以爬行的问题类型的例子。

只是想把任何有兴趣的人指给詹姆斯下面的答案。虽然上面的答案对于C仍然是正确的,但是新的C++标准(C++ 11)已经被改变,所以如果使用C++和符合C++ 11的编译器,则不再发出这个警告。

从C++ 11标准通过杰姆斯的帖子:

A source file that is not empty and that does not end in a new-line character, or that ends in a new-line character immediately preceded by a backslash character before any such splicing takes place, shall be processed as if an additional new-line character were appended to the file (C++11 §2.2/1).


在C++ 11中删除了每个源文件以非越出换行符结束的要求。现在规范如下:

A source file that is not empty and that does not end in a new-line character, or that ends in a new-line character immediately preceded by a backslash character before any such splicing takes place, shall be processed as if an additional new-line character were appended to the file (C++11 §2.2/1).

一致编译器不应该发出这个警告(至少在编译C++ 11模式时,如果编译器有不同的语言规范修订模式)。


C++ 03标准[2.1.21.]声明:

... If a source file that is not empty does not end in a new-line character, or ends in a new-line character
immediately preceded by a backslash character before any such splicing takes place, the behavior is undefined.


对"顺从"的回答是"因为C++ 03标准说,在新行中没有结束的程序的行为是未定义的"(释义)。

好奇者的答案是:http://gcc.gnu.org/ml/gcc/2001-07/msg01120.html。


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

大多数文本编辑器都会在文件的最后一行末尾放一个换行符,因此如果最后一行没有换行符,文件就有被截断的风险。但是,您可能不希望使用换行符有充分的理由,因此它只是一个警告,而不是一个错误。


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


因为如果文件没有以新的行结束,则C/C++版本之间的行为会不同。尤其是讨厌的C++版本,C++中的FX 03标准(翻译阶段):

If a source file that is not empty does not end in a new-line
character, or ends in a new-line character immediately preceded by a
backslash character, the behavior is undefined.

未定义的行为是不好的:一个标准一致的编译器可以或多或少地做它想做的事情(插入恶意代码或其他东西),这显然是一个警告的原因。

虽然在C++ 11中情况更好,但避免在早期版本中未定义行为的情况是一个好主意。C++ 03规范比C99更坏,它直接禁止这样的文件(行为然后被定义)。


Of course in practice every compiler adds a new line after the #include. Thankfully. – @mxcl

不是特定的C/C++,而是C方言:当使用EDCOX1×10扩展时,OSX上的GLSL编译器警告您没有丢失的换行符。所以你可以用一个以#endif // __MY_HEADER_H__结尾的header guard编写一个MyHeader.h文件,你肯定会在#include"MyHeader.h"之后丢失该行。


我使用的是无C-IDE版本5,在我的程序中,无论是c++还是c语言,我都遇到了同样的问题。只要在程序的最后一行,即程序的最后一行(在函数的括号之后,它可以是主函数或任何函数),按Enter行号将增加1。然后执行相同的程序,它将无差错地运行。


此警告还可能有助于指示某个文件可能以某种方式被截断。的确,编译器可能无论如何都会抛出一个编译器错误——特别是如果它在一个函数的中间——或者可能是一个链接器错误,但是这些错误可能更加神秘,而且不一定会发生。

当然,如果文件在换行后立即被截断,也不能保证此警告,但它仍然可能捕获其他错误可能会错过的某些情况,并对问题给出更强烈的提示。


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

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

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


展开全文阅读

相关内容