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

180 c++ compiler-construction warnings c-preprocessor

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

文件末尾没有换行符

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

TJ *_*oks 212

想想如果没有新行可能会出现的一些问题.根据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).

  • 当然,在实践中,每个编译器都会在#include之后添加一个新行.值得庆幸的. (26认同)
  • 我记得一个旧版本的Microsoft Visual C++(如2.x或其他东西)确实存在这个问题.由于IDE编辑器鼓励这种缺失的换行行为,因此它更加恶化. (3认同)
  • 编译器当前可能不会抱怨,但是GitHub实际上会抱怨。 (2认同)

Jam*_*lis 42

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

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

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

  • 这个问题被标记为[c ++]而不是[c]. (10认同)
  • 对C++来说,这一切都很好; 不幸的是,即使在最新的C1X标准草案中,C仍然表示它是UB. (4认同)
  • 即便如此,它可能*应该被标记为[c],因为许多在C中搜索此警告的人会在这里找到他们的方式. (2认同)

Igo*_*nov 24

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

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


Vyt*_*nis 15

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

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

  • 啊,亲爱的"未定义的行为".当其他语言失败时,c/c ++以"未定义"的方式运行:)当然,这是他们魅力的重要组成部分.而且我不是在开玩笑. (4认同)

Lei*_*ell 6

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

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


moo*_*dow 5

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