extern int n
nが(別のファイルで)宣言されているとコンパイルされないのに、宣言されているとstatic int n
動作するのはなぜint n
ですか?(これらの宣言は両方ともファイルスコープにありました。)
基本的に、int n
ファイルスコープ内static int n
が同じスコープ内と同じではないのはなぜですか?それはexternに関連しているだけですか?もしそうなら、externはどうですか?
の全体的な目的はstatic
、変数がで宣言されているソースファイルに対してプライベートであることを宣言することです。したがって、外部からの接続を防ぐという役割を正確に果たしています。
ファイルスコープ変数の定義には、次の4つの種類があることに注意してください。
int blah = 0;
— blahはこのファイルで定義されており、他のファイルからアクセスできます。他のファイルの定義は重複しており、エラーが発生します。extern int blah;
— blahは他の場所で定義する必要があり、このファイルから参照されます。int blah;
—これはFORTRANと道徳的に同等ですCOMMON
。これらはファイルにいくつでも含めることができ、それらはすべてリンカーによって1つの共有に解決されますint
。(*)static int blah;
(オプションでイニシャライザーを使用)—これは静的です。このファイルに対して完全にプライベートです。他のファイルのexternには表示されません。また、すべてが宣言されている多くの異なるファイルを持つことができstatic TYPE blah;
、それらはすべて異なります。聴衆の純粋主義者のために:'ファイル'=コンパイルユニット。
(ファイルスコープではなく)静的内部関数のスコープはさらに厳密であることに注意してください。2つの関数static int bleh = 0;
が同じファイル内でも宣言する場合、それらは無関係です。
(*):なじみのない人のために:通常のパターンでは、1つのコンパイルユニットがグローバル変数を定義する必要があり、他の人はそれを参照できます。それはそのコンパイルユニットに「住んでいる」。上記の(3)の場合、ファイル(またはすべてのファイル)で定義されていません。2つのファイルが言うint blah = 0;
場合、リンカは複数の定義について文句を言います。2つのファイルint blah;
がリンカが元気に単一のグローバルint
を作成し、すべてのコードがそれを参照するようにすると言っている場合。
標準Cでは、関数の外部で宣言された変数には2つのスコープがあります。変数は、それを宣言したstatic
コンパイルユニット(つまり、ファイル)内でのみ表示され、非静的変数はプログラム全体で表示されます。宣言によると、変数のextern
場所はまだわかっていませんが、リンカーによって分類されます。それは非静的変数と互換性がextern static
ありますが、ただの狂った話です!
もちろん、実際には、最近は他の可視性があります。特に、単一のソースファイルとプログラム全体のスコープレベルがあります。単一の共有ライブラリのレベルは便利です(GCC関数属性などのメカニズムを介して設定可能)。しかし、それは非静的変数のテーマの単なるバリエーションです。static
以前と同じ解釈を維持します。
MSDNのドキュメントによると:
変数を変更する場合、staticキーワードは、変数に静的期間(プログラムの開始時に割り当てられ、プログラムの終了時に割り当て解除)があることを指定し、別の値が指定されていない限り、変数を0に初期化します。ファイルスコープで変数または関数を変更する場合、staticキーワードは、変数または関数に内部リンクがあることを指定します(その名前は、宣言されているファイルの外部からは表示されません)。
MSDNの静的(C ++):2015年1月にアーカイブ。最新のドキュメントも参照してください:static§ストレージクラス(C ++)| Microsoft Docs
iv.c:2:1:エラー:宣言指定子の複数のストレージクラスextern static int i; ^
これが、静的変数を外部化しようとするときに得られるものです。extern staticintiを宣言します。-宣言floatintiに類似しています。floatとintを同じ宣言に含めることはできませんよね?同様に、同じ宣言にexternとstaticを含めることはできません。