一般に、実行可能ファイルのデータセグメントには初期化されたグローバル/静的変数が含まれ、BSSセグメントには初期化されていないグローバル/静的変数が含まれます。
ローダーがプログラムをメモリにロードすると、ユニバーサル化されたグローバル/静的変数は自動的にゼロで埋められます。
Cでは、関数内の静的変数(初期化されているかどうか)は、変数がローカル/関数スコープ(内部静的とも呼ばれることもあります)を持つことを意味しますが、それらは初期化されます。
したがって、fun()が呼び出された回数に関係なく、静的変数は、プログラムのロード時に1回だけ初期化されます。
staticと定義された変数は、まだデータセグメントまたはbssセグメントのいずれかに存在しますが、ファイルスコープのみを持っています。
コードをコンパイルすると、各オブジェクトファイルの一部であるインポートおよびエクスポートリストがあり、リンケージエディタで使用されます。静的変数はエクスポートリストにないため、他のオブジェクトファイルにはアクセスできません。
staticキーワードを除外することにより、グローバル変数はエクスポートリストに配置され、他のオブジェクトモジュールが参照することができ、リンケージエディタは実行可能ファイルを作成するときにシンボルを見つけることができます。絵画的表示のために
:
+--------- TEXT ---------+ Low memory
| main() |
| fun() |
+--------- DATA ---------+
| int a (global scope) |
| int c (file scope) |
| int e (function scope) |
+---------- BSS ---------+
| int b (global scope) |
| int d (file scope) |
| int f (function scope) |
+------------------------+
私は輸出list.Isそれシンボルテーブルであるかを理解できないのですか? – CrystalJake
要するに、各.o(オブジェクトファイル)の一部は、他のオブジェクトファイルに見えるエクスポートリスト(外部シンボルのリスト - グローバル変数/関数)です。また、オブジェクトファイル内で参照されていても別の場所で定義されているシンボルであるインポートリスト(グローバル変数/関数)があります。コンパイルのリンクフェーズでは、リンケージエディタはこれらのリストを使用してシンボルを結合します。 – ffhaddad