1

a)外部変数の定義は、ローカル変数の定義と同じです。つまり、int i=2;(すべての関数の外側でのみ)。しかし、なぜextern int i=2;定義として機能しすぎているのでしょうか。extern他のファイルの変数宣言でのみ使用されていませんか?

b)ファイル1

  #include<stdio.h>
  int i=3;
  int main()
  {
      printf("%d",i);
      fn();
  }

file2

  int i;  //  although the declaration should be: extern int i; So, why is this working?
  void fn()
  {
      printf("%d",i);
  }

出力:どちらの場合も3

4

2 に答える 2

5

歴史的な理由から、リンケージの決定と宣言が定義を提供する場合のルールは少し混乱しています。

あなたの特定の例では、ファイルスコープで

extern int i = 2;

int i = 2;

同等の外部定義です。つまりextern、初期化子を提供する場合はオプションです。

ただし、初期化子を提供しない場合は、オプションでexternはありません。

int i;

は、外部リンケージを使用した暫定的な定義であり、次のような外部定義になります。

int i = 0;

翻訳単位に明示的な初期化子を使用した別の定義が含まれていない場合。

これはとは異なります

extern int i;

これは決して定義ではありません。同じ識別子の別の宣言がすでに表示されている場合、変数はそこからリンクを取得します。これが最初の宣言である場合、変数には外部リンケージがあります。

これは、2番目の例では、file1とfile2の両方がの外部定義を提供することを意味します。iこれは未定義の動作であり、リンカーは最適な定義を自由に選択できます(デーモンを鼻から飛び出させようとする場合もあります)。Cには一般的な拡張機能があり(C99 Annex J.5.11およびこの質問を参照)、この特定のケースを明確に定義しています。

于 2012-05-04T17:20:52.223 に答える
1

Cでは、extern初期化を使用すると、変数が割り当てられます。つまり、宣言は定義宣言と見なされます。これは、のより一般的な使用法とは対照的ですextern

C規格は次のように述べています。

6.9.2外部オブジェクトの定義

....。

オブジェクトの識別子の宣言にファイルスコープと初期化子がある場合、その宣言は識別子の外部定義です。

int i質問の2番目の部分については、ファイルスコープでの宣言に外部リンクがあります。内部リンクを付与する場合は、宣言する必要がありますstatic int i。C規格は次のように述べています。

6.2.2識別子のリンク

.....。

オブジェクトの識別子の宣言にファイルスコープがあり、ストレージクラス指定子がない場合、そのリンケージは外部にあります。

于 2012-05-04T16:29:12.447 に答える