4

これら 3 つのバージョンの小さなプログラムを試してみたところ、興味深い結果が得られました。それぞれの場合のコンパイラの動作を理解するのを手伝ってくれませんか。

version 1.0

int A;
int A; 
int A;

int main ()
{
   return 0;
}

Result: Got compiled with one copy of A in BSS.


Version 2.0

int main ()
{
   int A;
   int A;
   int A;

   return 0;
}

Result: Failed to compile with complaining for re-declaration.


Version 3.0

int A;

int  main()
{
   static int A;
   return0;
}

result: Compiled with two copy of A in BSS. one is A and another a.<some numeric tag>. 
4

1 に答える 1

8

最初の例でint A;は、暫定的な定義です。初期化子を使用せず、ストレージ クラスまたはストレージ クラスを使用しないファイル スコープでの識別子の宣言ですstatic。複数のものを持つことができ、それらはすべて同じ変数を参照します。

規格には次のように記載されています: (ISO/IEC 9899:1999 6.9.2)

ファイル スコープを持ち、初期化子がなく、ストレージ クラス指定子がないか、またはストレージ クラス指定子 static があるオブジェクトの識別子の宣言は、暫定的な定義を構成します。翻訳単位に識別子の暫定的な定義が 1 つ以上含まれており、翻訳単位にその識別子の外部定義が含まれていない場合、動作は、翻訳単位にその識別子のファイル スコープ宣言が含まれているかのように、複合型は次のようになります。 0 に等しい初期化子を使用して、翻訳単位の末尾を指定します。

2番目の例でAは、ファイルスコープではありません。これはローカル変数であり、暫定的な定義ではないため、1 つしか持てません。

3 番目の例では、 at ファイル スコープは、スコープが異なるため、内部の main() とAは異なる変数です。A2 番目Aが静的であるという理由だけで、そのスコープは変更されません。識別子は引き続き main() 内からのみ表示されます。これは、あるスコープ内の変数が、それを囲むスコープ内の変数と同じ識別子を持つ変数シャドウイングのケースです (この場合、main() スコープとファイル スコープです) A。暫定的な定義は、A内部の main()には影響しません。

于 2013-01-17T11:26:11.007 に答える