web-dev-qa-db-ja.com

「ファイルの終わりに改行なし」コンパイラ警告

一部のC++コンパイラで次の警告が表示される理由は何ですか?

ファイルの終わりに改行なし

ソース/ヘッダーファイルの最後に空の行があるのはなぜですか?

180
LeChuck2k

改行がない場合に発生する可能性のある問題を考えてください。 ANSI規格によれば、最初のファイルの#includeはファイルの先頭にそのままファイルを挿入し、ファイルの内容の#include <foo.h>の後に新しい行を挿入しません。したがって、パーサーの最後に改行のないファイルを含めると、foo.hの最後の行がfoo.cppの最初の行と同じ行にあるかのように表示されます。 foo.hの最後の行が新しい行のないコメントであった場合はどうなりますか?これで、foo.cppの最初の行がコメント化されました。これらは、忍び寄ることができる問題の種類のほんの数例です。


ジェームズの下記の回答に関心のある関係者を向けたいだけです。上記の答えはCでも正しいのですが、新しいC++標準(C++ 11)が変更されたため、C++およびC++ 11に準拠したコンパイラを使用している場合、この警告は発行されません。

Jamesの投稿によるC++ 11標準から:

空ではなく、改行文字で終わらないソースファイル、またはそのようなスプライシングが行われる前にバックスラッシュ文字が直前にある改行文字で終わるソースファイルは、追加の改行文字として処理されます。行文字がファイルに追加されました(C++ 11§2.2/ 1)。

210
TJ Seabrooks

すべてのソースファイルがエスケープされていない改行で終わるという要件は、C++ 11で削除されました。仕様は次のとおりです。

空ではなく、改行文字で終わらないソースファイル、またはそのようなスプライシングが行われる前にバックスラッシュ文字が直前にある改行文字で終わるソースファイルは、追加の改行文字として処理されます。行文字がファイルに追加されました(C++ 11§2.2/ 1)。

準拠しているコンパイラーは、この警告を発行することはもうありません(少なくともC++ 11モードでコンパイルしている場合、コンパイラーが言語仕様の異なるリビジョンのモードを持っている場合は)。

42
James McNellis

C++ 03標準[2.1.1.2]宣言:

...空でないソースファイルが改行文字で終わらない場合、またはそのようなスプライシングが行われる前にバックスラッシュ文字が直前にある改行文字で終わる場合、動作は未定義です。

24
Igor Semenov

「従順」に対する答えは、「C++ 03標準では、改行で終わらないプログラムの動作は定義されていないからです」(言い換え)です。

好奇心の答えはこちらです: http://gcc.gnu.org/ml/gcc/2001-07/msg01120.html

15

空白行を参照するのではなく、最後の行(内容を含むことができる)が改行で終了するかどうかです。

ほとんどのテキストエディタは、ファイルの最終行の最後に改行を挿入するため、最終行に行がない場合、ファイルが切り捨てられるリスクがあります。ただし、改行が必要ない場合がある正当な理由があるため、改行ではなく警告にすぎません。

6
Leigh Caldwell

#includeは、その行をファイルのリテラル内容に置き換えます。ファイルが改行で終わらない場合、それをプルした#includeを含む行は次の行とマージされます。

5
moonshadow

もちろん、実際には、すべてのコンパイラーが#includeの後に新しい行を追加します。ありがたいことに。 – @mxcl

特定のC/C++ではなく、C方言:GL_ARB_shading_language_include拡張を使用する場合、OS Xのglslコンパイラーは、改行の欠落についてNOTを警告します。したがって、MyHeader.hで終わるヘッダーガードを使用して#endif // __MY_HEADER_H__ファイルを記述し、will#include "MyHeader.h"の後の行を確実に失うことができます。

2
Jan-Philip Loos

ファイルが改行で終わらない場合、C/C++バージョン間で動作が異なるためです。特に厄介なのは古いC++バージョン、C++ 03のfxであり、標準では次のように書かれています(翻訳段階):

空ではないソースファイルが改行文字で終わらない場合、またはバックスラッシュ文字の直前の改行文字で終わる場合、動作は未定義です。

未定義の振る舞いは悪いです:標準準拠のコンパイラは、ここで望んでいることを多少行うことができます(悪意のあるコードなどを挿入します)-明らかに警告の理由です。

C++ 11では状況は改善されますが、以前のバージョンでは動作が定義されていない状況を避けることをお勧めします。 C++ 03仕様は、このようなファイルを完全に禁止しているC99よりも劣っています(その後、動作が定義されます)。

2
skyking

私はc-free IDEバージョン5.0を使用しています。'c++ 'または' c '言語のいずれかのプログラムで同じ問題が発生していました。ただプログラムの最後すなわちプログラムの最後の行(関数の中括弧の後、メインまたは任意の関数になる可能性があります)、enterを押す-line no。 1ずつ増加し、同じプログラムを実行すると、エラーなしで実行されます。

2
divesh

この警告は、ファイルが何らかの理由で切り捨てられた可能性があることを示すのにも役立ちます。とにかくコンパイラーはおそらくコンパイラーエラーをスローすることは確かです-特に関数の途中にある場合-またはおそらくリンカーエラーですが、これらはより不可解であり、発生が保証されていません。

もちろん、改行の直後にファイルが切り捨てられた場合にもこの警告は保証されませんが、他のエラーが見逃す可能性のあるケースをキャッチでき、問題のより強力なヒントを提供します。

0
mwfearnley