web-dev-qa-db-ja.com

local、global、static、auto、register、extern、const、volatile変数はどこに保存されますか?

Local、global、static、auto、register、extern、const、volatile変数はどこに保存されますか?

29
Matrix
  • local変数は、自動か静的かに応じて、スタックまたはデータセグメントに格納できます。 (autoもstaticも明示的に指定されていない場合、autoが想定されます)

  • global変数はデータセグメントに格納され(コンパイラが変数を最適化できない限り、constを参照)、宣言の時点からコンパイル単位の終わりまで可視性があります。

  • static変数はデータセグメントに格納され(コンパイラがそれらを最適化できない限り)、宣言の時点から囲みスコープの終わりまで可視性があります。静的ではないグローバル変数は、他のコンパイル単位でも表示されます(externを参照)。

  • auto変数は常にローカルであり、スタックに保存されます。

  • register修飾子は、可能な限り変数をレジスタに保持するために最善を尽くすようコンパイラーに指示します。それ以外の場合は、スタックに保存されます。

  • extern変数はデータセグメントに保存されます。 extern修飾子は、異なるコンパイル単位が実際に変数を宣言していることをコンパイラーに伝えるため、そのインスタンスを作成しないでください。そうしないと、リンク時に名前の衝突が発生します。

  • const変数は、自動か静的かに応じて、スタックまたは読み取り専用データセグメントに格納できます。ただし、コンパイラーが別のコンパイル単位から参照できない、またはコードがconst変数のアドレスを使用していないと判断できる場合、それを最適化して自由に使用できます(各参照は定数値に置き換えることができます) 。その場合、どこにも保存されません。

  • volatile修飾子は、変数の値が外部の影響(通常はハードウェア)からいつでも変化する可能性があることをコンパイラに伝えるため、その変数が参照されるときにメモリからレジスタへのリロードを最適化しよう。これは、静的ストレージを意味します。

ところで、これはすべて、CおよびC++とObjective-Cに適用されます。

60
Ferruccio

どのレベルの抽象化で答えを探していますか?

物理レベルでは、それらはすべてゲート容量と磁区に保存されている可能性があります。 (スワップディスクがWi-Fiまたは光ファイバーに接続されている場合は、フォトンもあります。)

1つのハードウェアレベルでは、これらの変数のすべてのコピーが、レジスタ、データキャッシュ(おそらく複数レベル)、メインメモリ、ストレージ階層のいくつかの場所に存在し、ディスクまたはNVストレージに完全にスワップアウトされます。 (デマンドページ仮想メモリサブシステムの存在、実装、および現在の状態に応じて)、アプリのサイズとライフタイムが十分に小さい場合は、おそらくレジスタ内のすべてに。

最もよく知られているコンパイラとランタイムの実装を考えると、メモリ(おそらく仮想)はスタックとヒープと呼ばれるものに切り刻まれます。正式な言語定義を考えると、このチョッピングは必要な場合とそうでない場合があります。

コンパイラー最適化レベルでは、これらの変数の多くは存在しない状態で最適化されている場合があります。それらは、抽象化として以外にはどこにも保存されません。

11
hotpaw2

ローカル変数とauto変数はスタックに保存されます。グローバル変数とstatic変数はDATAページに保存されます。 register変数は、可能であればCPUのレジスタに格納され、それ以外の場合はスタックに格納されます。 externconst、およびvolatileは、変数の保存場所を指定しません。変数は、他のストレージ指定子が存在する場所に保存されます。

通常、ローカル変数はスタックに格納され、グローバル変数はプログラムの「テキスト」セグメント(文字列定数の場合)または動的に割り当てられる場合はヒープに格納されます。通常、自動変数は関数/メソッドで使用され、通常はスタックに渡されます(アーキテクチャによっては、レジスタにも渡される場合があります)。レジスター変数は、一度レジスターに格納されていましたが、最近のほとんどのコンパイラーは、registerキーワードを無視し、スタックまたはレジスターの適切な場所に配置します。 Extern、const、volatileメンバーは修飾子であるため、それらが格納される明確な場所はありません。

したがって、短い答えは、いつものように、「それは依存します」です。

2
mipadi

LOCAL-関数内にスコープが含まれるローカル変数。自動または静的の2つのタイプがあります。単純に宣言されている場合、int var.Compilerは自動ストレージクラスとして扱います。自動変数はStackに保存されます。静的変数はデータセグメントに保存されます。

レジスタ変数はCPUに保存されます。変数を保存できるレジスタがない場合、コンパイラは自動変数として処理します。

グローバル変数はデータセグメント領域に保存されます。

Const変数は読み取り専用領域に格納されます。これは記憶のコードセグメント領域です。

1
Subrat