在某些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;。