9

重複の可能性:
C 関数に対する「extern」キーワードの影響

さて、ここ数時間、extern キーワードの意味について多くのことを読みました。最後にもう 1 つ、私が情報を見つけることができずに私を悩ませていることがあります。私が理解している限り、externキーワードは基本的に、変数または関数が単なる宣言であり、どこかで定義されていることをコンパイラに伝えているため、それについて心配する必要はなく、リンカが処理します。

そして、これを入力するとコンパイラ(私はgcc 4.2.1を使用しています)によって生成された警告:

extern int var = 10;

これをサポートします。これexternは宣言のみのはずなので正しくありません。

ただし、私を混乱させているのは、これを入力するときに警告などが表示されないことです。

extern int func() {return 5;}

これは定義であり、同じ警告を生成する必要がありますが、そうではありません。ここで見つけた唯一の説明は、定義がexternキーワードをオーバーライドするということです。ただし、そのロジックに従って、変数定義である場合にオーバーライドしないのはなぜですか? または、キーワードを変数と一緒に使用すると、特別な意味がありますか?

誰かが私にこれを説明してくれたら、とてもありがたいです。ありがとうございました!

4

2 に答える 2

5

externキーワードは、変数で使用される場合にのみ特別な意味を持ちます。extern関数プロトタイプでの使用は完全にオプションです。

extern void foo(int bar);

と同等です

void foo(int bar);

関数を宣言/定義するときは、次の2つのオプションがあります。

  1. 宣言(つまりプロトタイプ)のみを提供するか、または
  2. プロトタイプがない場合の宣言としても機能する定義を提供します。

ただし、変数を使用する場合は、次の3つのオプションがあります。

  1. 宣言のみを提供し、
  2. デフォルトの初期化子を使用して定義を提供します:部分int var;なし= 10、または
  3. 特定の初期化子で定義を提供します。int var = 10

extern関数には2つのオプションしかないため、コンパイラーはキーワードを使用せずにそれを区別できます。staticデフォルトでは、キーワードを含まない宣言が考慮externされます。したがって、externキーワードはすべての関数宣言または定義で無視されます。

ただし、変数の場合、#1と#2を区別するためにキーワードが必要です。を使用するexternと、それは#1です。使わないときはextern#2です。extern#3に追加しようとすると、それは定義のままであり、extern無視されるため、警告です。

これらはすべて多少単純化されています。同じコンパイル単位で宣言を複数回提供でき、グローバルスコープまたはブロックスコープで宣言を提供できます。詳細については、C規格のセクション6.7.95を確認してください。

于 2013-02-03T12:00:28.793 に答える
3

しかし、そのロジックに従うと、変数定義の場合にオーバーライドされないのはなぜですか?または、変数とともに使用する場合、キーワードには特別な意味がありますか?

変数と関数の違いは

void foo();

関数宣言ですが、

int i;

変数定義です。

複数のファイルに変数定義がある場合、コンパイラーはその変数のストレージを複数回生成します(おそらく、リンカーエラーが発生します)。これは関数には当てはまりません。

于 2013-02-03T11:58:20.810 に答える