在某些C++编译器中,下面的警告是什么原因?
No newline at end of file
为什么在源文件/头文件的末尾应该有一个空行?
不完全是因为这个原因,但是如果您使用cx1〔0〕文件,并且它没有尾随新行,因为新的shell提示将出现在文件的最后一行之后(即,不在第0列中),这会非常烦人。
@因为这个原因,我的$PS1从一个新行开始。(无论如何,它是一个多行提示,在一行中包含大量有用的信息,然后在下一行中只包含一个提示字符,这样相当长的命令就不会换行了)
Why should I have an empty line at the end of a source/header file—如果文本文件包含one
two
three,则它包含三行,其中没有一行是空的。如果文本文件包含one
two
three,那么它不是文本文件,从同样的意义上说,结尾没有句号的句子不是句子。
想想如果没有换行符可能会出现的一些问题。根据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).
当然,在实践中,每个编译器都会在include后面添加一行新行。谢天谢地。
我记得一个旧版本的微软Visual C++(比如2。x或某物)正好有这个问题。这是因为IDE编辑器鼓励这种缺少新行的行为而加剧的。
编译器目前可能不会抱怨,但Github确实会抱怨。
我可以看到詹姆斯的"下面"答案,但"上面的答案"顺序是什么?!以上是我通常按投票顺序排列的问题。或者你是说你自己的答案?
@托马斯:这个程序调用未定义的行为是因为它没有以新行结尾吗?参见下面的程序:ideone.com/jswwf9
在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++来说都是好的,不幸的是,C仍然说它是UB,甚至在即将到来的C1X标准的最新草案中。
这个问题被标记[C++]而不是[C]。
尽管如此,它可能应该被标记为[C],因为许多在C中搜索这个警告的人会找到他们的方法。
这仍然是一个很好的补充。把这个加在上面。希望你不介意。
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。
啊,亲爱的"不明确的行为"。当其他语言失败时,C/C++以"未定义"的方式运行:当然,这是它们魅力的一大部分。我不是开玩笑。
它不是指空行,而是指最后一行(可以包含内容)是否以换行符结束。
大多数文本编辑器都会在文件的最后一行末尾放一个换行符,因此如果最后一行没有换行符,文件就有被截断的风险。但是,您可能不希望使用换行符有充分的理由,因此它只是一个警告,而不是一个错误。
#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更坏,它直接禁止这样的文件(行为然后被定义)。
我怀疑该标准说,没有后置新行的程序具有未定义的行为,而不是说它们是格式错误的,因为有些编译器会将包含文件的未终止的最后一行与遵循#include指令的源代码文本连接起来,而一些针对此类编译器的程序员可能会利用了这种行为。如果标准没有定义这些东西,那么利用这些特性的程序就可以在指定这些行为的平台上得到很好的定义。有了标准的授权,行为就会破坏这样的计划。
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;。