Cでは、静的変数はどこに格納されていますか? 2つの静的変数があるとします.1つは関数に対してローカルであり、もう1つはグローバルです。このエントリはシンボルテーブルでどのように管理されていますか?説明してください。静的変数記憶
静的変数記憶
答えて
では、インプリメンテーションが適切とみなされる場所に格納できます。 Cの標準は、実装がどのようにして動作するかを指示するものではなく、の動作のみを指示します。
通常、すべての静的記憶期間変数(関数内の静的変数および関数外のすべての変数)は、ファイルレベルでの関数であるか関数内であるかにかかわらず、同じ領域に格納されます。
上記のかっこ内のビットが重要です。関数の外では、static
は関数内でのように変数の格納期間を決定しません。変数が現在の翻訳単位の外側に表示されているかどうかを判断します。 すべて関数外の変数は、静的な記憶期間です。
シンボルテーブルに関しては、ビルドプロセス中にのみ存在するコンストラクトです。実行ファイルが生成されると、シンボルはありません(デバッグ情報はもちろん除外されますが、コードの実行とは関係ありません)。その時点での変数への参照はすべて、ハードコーディングされたアドレスまたはオフセットになります。
つまり、どの変数を参照しているのかを名前で調べるのはコンパイラです。
ここでは、変数の格納方法の例を参照できます。以下の小さなCプログラムを考えてみましょう:
#include <stdio.h>
int var1;
static int var2;
int main (void) {
int var3;
static int var4;
var1 = 111;
var2 = 222;
var3 = 333;
var4 = 444;
return 0;
}
これは、次のアセンブリを生成:
.file "qq.c"
.comm var1,4,4
.local var2
.comm var2,4,4
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
subl $16, %esp
movl $111, var1
movl $222, var2
movl $333, -4(%ebp)
movl $444, var4.1705
movl $0, %eax
leave
ret
.size main, .-main
.local var4.1705
.comm var4.1705,4,4
.ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
.section .note.GNU-stack,"",@progbits
をそして、あなたはvar1
、var2
とvar4
(静的記憶域期間のもの)はすべてに.comm
ラインを持っていることがわかりますそれらをリンカによる統合の対象となる共通エントリとしてマークします。リンカーは、他のオブジェクト・ファイルに未解決の外部を満たすためにそれらを使用しないように
、var2
、var3
及びvar4
(現在transdlation部外見えないもの)はすべて、.local
ラインを有しています。
そして、ファイルをリンクしながら、ld --verbose
の出力を調べることによって、あなたはすべての一般的なエントリは.bss
エリアに終わることがわかります。
static int a_static_var = 5;
void foo(void)
{
static int a_static_var = 6;
return;
}
:以下のソースを考えると
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
: : :
}
Cコードからasmコードを生成するために使用したツール。 –
@prp、 'gcc -S'はアセンブリコードを標準出力に出力します。 – paxdiablo
本当にthnx男..あなたはコンパイラでオタクのように思える.. –
すべてのコンパイラに一般化することは不可能ですが、これは最も頻繁に行われます。
ロード時に初期化されますが、実行時に変更可能な変数のリンカーによって、メモリブロックが確保されます。すべての静的変数は、ローカルかグローバルかに関係なく、このブロックに配置されます。
Visual Studioは以下のように変数をコンパイルします(この例では、詳細はコンパイラごとに異なり、オプションによって異なります)。
_DATA SEGMENT
_a_static_var DD 05H
[email protected][email protected]@[email protected] DD 06H ; `foo'::`2'::a_static_var
_DATA ENDS
したがって、両方の静的変数はデータセグメントになります。関数にスコープされた静的変数は、別の関数またはソースファイルと同様の変数と「一致」しないように名前が変更されています。
コンパイラの実装ではこれは自由に処理できますが、一般的な考え方は通常似ています。
Cにはシンボルテーブルがありますか? – leppie
"静的変数"とはどういう意味ですか?静的記憶期間?または内部リンケージ? – AnT