2017-01-30 7 views
2

私のCプログラムをコンパイルするにはGCCのGnu ccコンパイラを使用しています。私はプリプロセッサラインがプリプロセッサによって処理されるとどうなりますか? - '.i'ファイル

cpp sample.c > sample.i 

を使用して、上記のコードのプリプロセスをするとき、私は私が含まれていないsample.i内のコンテンツの多くを得る、プログラム、今

#include <stdio.h> 
int main(){ 
    return 0; 
} 

を考えてみましょう。 「stdio.h」ファイルが前処理されているとします。その場合は、

質問1:

はなぜ私の前処理ファイルで非常に多くの行があるのですか? I は、標準ライブラリ関数もマクロも使用していません。

質問2:

誰でもプリプロセッサがCファイルをproccess時に正確に何が起こるかを説明することができます(私は '* .I' ファイルになった内容)

コンパイラ:GCC

OS:Ubuntuの

おかげ

+0

これは文字通りインクルードファイルを開き、内容をその場でコピーします。 ''も他のファイルも '#インクルード 'するとコピーされます。そういうわけで、頼んだとは思っていなかったほどのものを手に入れます。 – BoBTFish

答えて

4

なぜ私の前処理ファイルで非常に多くの行があるcplusplus.comに非常に良い(と短い)のガイダンスがありますか?私は標準ライブラリ関数やマクロを使用していません。

前処理は、コンパイル処理の一部に過ぎません。それは多かれ少なかれ単純なテキストの置き換えであり、前処理段階で複雑なものは何もありません。プリプロセッサは、コードプログラムで標準関数を使用したかどうかを知らないか、気にしません。 (コンパイルプロセスの一部としての)オプティマイザは、不要な部分を「削除」する可能性があります。 しかし、プリプロセッサはそれをしません。 これはインクルードしたすべてのヘッダーファイルとヘッダーファイルなどに含まれるその他のヘッダーファイルの前処理を行います。

プリプロセッサプロセスCファイル(私は「* .I」ファイルに入った内容は)

前処理はかなりの数の作業を伴う場合誰もが正確に何が起こるかを説明できます:マクロ置換、条件付きコンパイル、ストリング、ストリング連結など あなたはここでは詳細にcpp詳細を読むことができます:あなたがそれらを使用することはできませんhttps://gcc.gnu.org/onlinedocs/cpp/

3

preproces sorコマンド#include "aFile.h"は、aFile.hの穴の内容をcppファイルに入れます。そしてそれはプリプロセッサ命令が立っている場所に正確に当てはまります。これがaFile.hで定義された関数を使用できる理由です。

あなたはプリプロセッサについての詳細を学ぶために関心がある場合、

+1

stdio.hファイルの内容をコピーするのはなぜですか(ライブラリ関数やマクロはありません)。 –

+1

プリプロセッサは気にしません。 – LogicStuff

+1

あなたはまだそれを使用していませんが、それは可能です。必要がない場合は、includeステートメントを削除できます。 – Soeren

1

1)、しかし、あなたはあなたから来る何を参照してくださいどこだ

#include <stdio.h> 

ライン1にそれらが含まれています。違いを確認するためにそれを削除してみてください。

2)プリプロセッサは、Cファイルを読み込み、宣言したプリプロセッサディレクティブをすべて処理しました。すべてのプリプロセッサディレクティブは、「#」記号で始まります。 '#include'は、この行を指定されたファイルの内容で置き換えます。古典的な '#ifndef'と '#define'ディレクティブもあります。後者はので、あなたはシンボルが定義されている場合のみ、コードの一部を活性化させることを可能声明「が」

#ifndef _SOME_SYMBOL_ 
#define _SOME_SYMBOL_ 

#ifndef WIN32 
#include <some_file.h> 
#else 
#include <some_other_file.h> 
#endif 

int main() { return 0;} 

#endif //endof _SOME_SYMBOL_ 

#ifndef _SOME_SYMBOL_ 
#define _SOME_SYMBOL_ 

// this second function is ignored 
int main() { return 0;} 

#endif //endof _SOME_SYMBOL_ 

プリプロセッサは、上記のファイルを読み込み

、記号「_SOME_SYMBOL_」は不明であるに等しいですプリプロセッサはそれを初期化します。次に、 WIN32を知っているかどうかにかかわらずファイルが含まれます。通常、この種のシンボルはコマンドラインを通って渡されます。したがって、コードの一部が動的に有効化または無効化されます。

プリプロセッサは出力この

void some_other_function_from_some_other_file(){} 

int main() { return 0;} 
3

プリプロセッサはテキスト置換を行います。 #include <stdio.h>の正味の効果は、#include <stdio.h>行を<stdio.h>の内容で置き換えることです。

実際、<stdio.h>は、様々な機能のいくつかの宣言(例えばfprintf()fscanf())、変数の宣言(例えばstdoutstdin)、およびいくつかのマクロ定義(これは、後のコードで使用される場合、テキスト置換を引き起こす)を含みます。

プリプロセッサはソースコードを入力として使用し、必要に応じてテキストを置き換えます(例:#include、マクロ展開など)。結果のソースコードを出力します。その出力は、コンパイルの段階である

など、あなたがsample.i

にプリプロセッサの出力を指示しているもので、実際に宣言を理解し、コンパイルの後の段階に入力され、定義、ステートメントシーケンシャル - 順次に発生します。したがって、コンパイルの後のフェーズでは、プリプロセッサに何の情報も戻されません。宣言などが使用されているかどうかを検出するのは、コンパイルの後の段階です。しかし、そのような情報をプリプロセッサに戻すことはできないので(とにかく、プリプロセッサはそのような情報を使用できない無知なプログラムです)、プリプロセッサは宣言が未使用であることを知ることができず、フィルタリングします。

関連する問題