一部のC++コンパイラで次の警告が表示される理由は何ですか?
ファイルの終わりに改行なし
ソース/ヘッダーファイルの最後に空の行があるのはなぜですか?
改行がない場合に発生する可能性のある問題を考えてください。 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)。
すべてのソースファイルがエスケープされていない改行で終わるという要件は、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 。
空白行を参照するのではなく、最後の行(内容を含むことができる)が改行で終了するかどうかです。
ほとんどのテキストエディタは、ファイルの最終行の最後に改行を挿入するため、最終行に行がない場合、ファイルが切り捨てられるリスクがあります。ただし、改行が必要ない場合がある正当な理由があるため、改行ではなく警告にすぎません。
#include
は、その行をファイルのリテラル内容に置き換えます。ファイルが改行で終わらない場合、それをプルした#include
を含む行は次の行とマージされます。
もちろん、実際には、すべてのコンパイラーが#includeの後に新しい行を追加します。ありがたいことに。 – @mxcl
特定のC/C++ではなく、C方言:GL_ARB_shading_language_include
拡張を使用する場合、OS Xのglslコンパイラーは、改行の欠落についてNOTを警告します。したがって、MyHeader.h
で終わるヘッダーガードを使用して#endif // __MY_HEADER_H__
ファイルを記述し、will#include "MyHeader.h"
の後の行を確実に失うことができます。
ファイルが改行で終わらない場合、C/C++バージョン間で動作が異なるためです。特に厄介なのは古いC++バージョン、C++ 03のfxであり、標準では次のように書かれています(翻訳段階):
空ではないソースファイルが改行文字で終わらない場合、またはバックスラッシュ文字の直前の改行文字で終わる場合、動作は未定義です。
未定義の振る舞いは悪いです:標準準拠のコンパイラは、ここで望んでいることを多少行うことができます(悪意のあるコードなどを挿入します)-明らかに警告の理由です。
C++ 11では状況は改善されますが、以前のバージョンでは動作が定義されていない状況を避けることをお勧めします。 C++ 03仕様は、このようなファイルを完全に禁止しているC99よりも劣っています(その後、動作が定義されます)。
私はc-free IDEバージョン5.0を使用しています。'c++ 'または' c '言語のいずれかのプログラムで同じ問題が発生していました。ただプログラムの最後すなわちプログラムの最後の行(関数の中括弧の後、メインまたは任意の関数になる可能性があります)、enterを押す-line no。 1ずつ増加し、同じプログラムを実行すると、エラーなしで実行されます。
この警告は、ファイルが何らかの理由で切り捨てられた可能性があることを示すのにも役立ちます。とにかくコンパイラーはおそらくコンパイラーエラーをスローすることは確かです-特に関数の途中にある場合-またはおそらくリンカーエラーですが、これらはより不可解であり、発生が保証されていません。
もちろん、改行の直後にファイルが切り捨てられた場合にもこの警告は保証されませんが、他のエラーが見逃す可能性のあるケースをキャッチでき、問題のより強力なヒントを提供します。