某些C ++编译器中出现以下警告的原因是什么?
文件末尾没有换行符
为什么我应该在源/头文件的末尾有一个空行?
答案 0 :(得分:207)
想想如果没有换行符可能会出现的一些问题。根据ANSI标准,开头文件的#include
将文件完全按原样插入到文件的前面,并且不会在文件内容之后的#include <foo.h>
之后插入新行。因此,如果您在解析器的末尾包含一个没有换行符的文件,它将被视为foo.h
的最后一行与foo.cpp
的第一行在同一行。如果foo.h的最后一行是没有换行的注释怎么办?现在foo.cpp
的第一行被注释掉了。这些只是可能出现的问题类型的几个例子。
只是想让任何感兴趣的人向詹姆斯的回答指出。虽然上述答案对于C仍然是正确的,但新的C ++标准(C ++ 11)已经更改,因此如果使用C ++和符合C ++ 11的编译器,则不应再发出此警告。
从C ++ 11标准到詹姆斯的帖子:
源文件非空并且不以换行符结尾,或者在任何此类拼接发生之前以反斜杠字符开头的新行字符结尾处理,如同附加的换行符附加到文件中(C ++11§2.2/ 1)。
答案 1 :(得分:42)
要求在C ++ 11中删除每个以非转义换行符结尾的源文件。该规范现在为:
源文件非空并且不以换行符结尾,或者在任何此类拼接发生之前以反斜杠字符开头的新行字符结尾处理,如同附加的换行符附加到文件中(C ++11§2.2/ 1)。
符合标准的编译器不应再发出此警告(至少在C ++ 11模式下编译时,如果编译器具有不同版本的语言规范的模式)。
答案 2 :(得分:24)
C ++ 03标准[2.1.1.2]声明:
...如果非空源文件不以换行符结尾,或以换行符结尾
。在任何此类拼接发生之前,前面紧跟一个反斜杠字符。
答案 3 :(得分:15)
“顺从”的答案是“因为C ++ 03标准说未以新行结尾的程序行为未定义”(转述)。
答案 4 :(得分:6)
它不是指空行,而是最后一行(可以包含其中的内容)是否以换行符结束。
大多数文本编辑器会在文件的最后一行末尾添加换行符,因此如果最后一行没有换行符,则存在文件被截断的风险。但是,有充分的理由说明为什么您可能不需要换行符,因此它只是一个警告,而不是错误。
答案 5 :(得分:5)
#include
会将其行替换为文件的文字内容。如果文件没有以换行符结尾,则包含将其拉入的#include
的行将与下一行合并。
答案 6 :(得分:2)
我正在使用c-free IDE 5.0版,在我的程序中使用'c ++'或'c'语言我遇到了同样的问题。只需在程序结束时即最后一行程序(在功能大括号之后它可能是主要的或任何功能),按回车 -line no。将增加1.然后执行相同的程序,它将运行没有错误。
答案 7 :(得分:2)
当然,在实践中,每个编译器都会在#include之后添加一个新行。值得庆幸的。 - @mxcl
不是特定的C / C ++而是C语言:当使用GL_ARB_shading_language_include
扩展名时,OS X上的glsl编译器会警告您 NOT 关于缺少的换行符。因此,您可以使用以MyHeader.h
结尾的标题保护编写#endif // __MY_HEADER_H__
文件,并且将在#include "MyHeader.h"
之后确定丢失该行。
答案 8 :(得分:2)
因为如果文件不以换行符结尾,则C / C ++版本之间的行为会有所不同。特别令人讨厌的是旧的C ++ - 版本,fx在C ++ 03标准中说(翻译阶段):
如果非空的源文件不以换行符结尾 字符,或以紧接在a之后的换行符结尾 反斜杠字符,行为未定义。
未定义的行为很糟糕:符合标准的编译器可以在这里做或多或少的事情(插入恶意代码或其他内容) - 显然是警告的原因。
虽然在C ++ 11中情况更好,但最好避免在早期版本中未定义行为的情况。 C ++ 03规范比完全禁止此类文件的C99更糟糕(然后定义了行为)。
答案 9 :(得分:0)
此警告也可能有助于指示文件可能以某种方式被截断。确实,编译器可能会抛出编译器错误 - 特别是如果它位于函数中间 - 或者可能是链接器错误,但这些可能更加神秘,并且不能保证会发生。
当然,如果文件在换行符后立即被截断,也无法保证此警告,但它仍然可以捕获其他错误可能会遗漏的情况,并提供更强的问题提示。
答案 10 :(得分:-2)
这不是错误。这只是一个警告。
在编辑器中打开文件,转到文件的最后一行,然后按Enter键在文件末尾添加一个空行。
除此之外,您应该使用#include <iostream>
代替<iostream.h>
。然后在using std::cout;
之后输入。