2009-08-25 9 views
14

他のモジュール(他のファイル)の変数/関数にアクセスするために使用される "extern"キーワードの有用性について疑問を持ち始めています。 #includeプリプロセッサを使用して、変数/関数プロトタイプまたは関数/変数定義を持つヘッダファイルをインポートするときにも同じことをしていませんか?externと#includingヘッダファイルを使用する違いは何ですか?

答えて

17

externシンボルが存在し、特定のタイプのものであると宣言し、そのための記憶域を割り当てないため、必要です。

そうした場合:複数のソースファイル間で共有されているヘッダファイルに

int foo; 

を各ソースがfooの独自のコピーを作成しなければならないと、リンカーはできませんので、あなたはリンカエラーが発生しますシンボルを解決する。

代わりに、あなたが持っている場合:ヘッダで

extern int foo; 

、それは、各ソースファイルの別の場所で定義されたシンボルを宣言します。

1つだけのソースファイルは、解決するリンカーのFOOの単一のインスタンスを作成

int foo; 

を含むであろう。

+2

しかし、定義を含むヘッダファイルをインクルードしていれば、extern int fooで宣言することなくint fooにアクセスできますか? –

+2

jcopenhaが言及しているように、#includeはインクルードファイルのテキストをソースファイルに挿入するだけです。コンパイラはインクルードファイルを本当に認識せず、特別に処理しません。ですから、それぞれが "int foo"を持ち、それらをリンクしているA.c、B.c、C.cを持っているなら、どのようにfooを解決しますか?それは3つの異なる場所に存在します。 externは、シンボルがどこかに存在することを意味します。あなたはそれを使うことができますが、誰かがそれを作成する責任があります。 – Michael

+0

foo_fun()のインスタンスが1つしかない関数では、foo_fun()を呼び出すモジュールがexternの有無にかかわらず動作することがわかります。だから、あなたはそれについて明確にしようとするべきです。共有グローバル変数に入るときには、本当に明確にする必要がありますが、コンパイラによってはそれを把握するものもあれば、そうでないものもあります。 –

2

いいえ#includeは "この他のファイルのすべてのテキストをここに置く"というプリプロセッサコマンドです。したがって、インクルードされたファイルのすべての関数と変数は、現在のファイルで定義されています。

関連する問題