在某些C ++编译器中发出以下警告的原因是什么?
文件末尾没有换行符
为什么在源/头文件的末尾应该有一个空行?
Why should I have an empty line at the end of a source/header file
-如果文本文件包含one\ntwo\nthree\n
三行,则其中三行都不为空。如果一个文本文件包含one\ntwo\nthree
一个文本文件,则它不是文本文件,从某种意义上说,结尾没有句号的句子不是句子。
在某些C ++编译器中发出以下警告的原因是什么?
文件末尾没有换行符
为什么在源/头文件的末尾应该有一个空行?
Why should I have an empty line at the end of a source/header file
-如果文本文件包含one\ntwo\nthree\n
三行,则其中三行都不为空。如果一个文本文件包含one\ntwo\nthree
一个文本文件,则它不是文本文件,从某种意义上说,结尾没有句号的句子不是句子。
Answers:
想想如果没有换行符可能会发生的一些问题。根据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)。
C ++ 11中删除了每个源文件都以不转义的换行符结尾的要求。规范现在显示为:
源文件不为空且不以换行符结尾,或者在任何此类拼接发生之前以反斜杠字符开头的换行符结尾的源文件,应被视为附加的换行符,行字符已附加到文件中(C ++ 11§2.2/ 1)。
合格的编译器不应再发出此警告(如果编译器具有用于语言规范的不同版本的模式,则至少在以C ++ 11模式编译时不应该发出此警告)。
C ++ 03标准[2.1.1.2]声明:
...如果非空的源文件没有以换行符结尾,或者以任何反斜杠字符开头的换行符结尾(在进行任何此类拼接之前),则行为未定义。
“服从”的答案是“因为C ++ 03标准指出未定义以换行符结尾的程序的行为”(解释)。
好奇的答案在这里:http : //gcc.gnu.org/ml/gcc/2001-07/msg01120.html。
因为如果文件不以换行结尾,则行为在C / C ++版本之间会有所不同。特别讨厌的是较旧的C ++版本,标准说的C ++ 03中的fx(翻译阶段):
如果不为空的源文件没有以换行符结尾或以反斜杠字符开头的换行符结尾,则该行为是未定义的。
未定义的行为是不好的:符合标准的编译器可能在这里或多或少地执行其想要的操作(插入恶意代码或其他内容),这显然是发出警告的原因。
尽管在C ++ 11中情况较好,但最好避免在早期版本中未定义行为的情况。C ++ 03规范比C99差,后者完全禁止此类文件(然后定义行为)。
#include
指令后面的源代码文本连接起来,并且某些针对此类编译器的程序员可能已经利用了此类行为。使标准使此类事物保持未定义状态将使利用此类怪癖的程序在指定此类行为的平台上得到良好定义。具有标准强制性的行为会破坏此类程序。
cat
是文件且它没有尾随换行符,则很烦人,因为新的Shell提示符将出现在文件的最后一行之后(即不在列0中)