シンボル テーブルは、名前をプログラム内の構造にマップします。そのため、クラス、関数、変数、およびプログラム内でユーザーが指定した名前を持つその他すべての名前を記録するために使用されます。
(シンボル テーブルには 2 つの一般的な種類があります。1 つはコンパイラがプログラムをコンパイルするときに保持するもの、もう 1 つは他のオブジェクトにリンクできるようにオブジェクト ファイルに存在するものです。この 2 つは強く関連していますが、似ている必要はありません。通常、コンパイラのシンボル テーブルの一部のシンボルのみがオブジェクトに出力されます)。
あなたの言うことの一部は意味がありません:
ワンパスでコードをコンパイルする場合、シンボル テーブルにクラス名とサブルーチン名を格納する必要はありません。
コンパイラは、シンボル テーブルで名前を参照できない場合、名前が参照する構造をどのように判断できますか?
ただし、マルチパス コンパイラの場合は、検出したクラスとそのサブルーチンに関する情報を追加して、引数の型チェックを実行し、意味のあるエラー メッセージを発行できます。
1 回のパスでこれを実行できない理由はありません。
実際にコンパイラに依存しているかどうかを理解できませんでしたか?
すべてのコンパイラはシンボル テーブルを使用しますが、その使用は実装内に隠されます。
私は、コンパイラー (C++ コードの場合) が、シングルパスコンパイラーであろうとマルチパスコンパイラーであろうと、関数名とクラス名をテーブルに入れると想定していました。パスにどのように依存していますか?
パスに依存するものは何ですか? すべての名前はシンボルテーブルに入れられます-それが目的です-そして通常、シンボルの解決はコンパイラが行う他のすべてのことにとって重要です。マルチパス コンパイラ コンパイラの最初のパスは、シンボル テーブルを構築するためだけかもしれません!)。
さらに、単純な C++ クラスのサンプル シンボル テーブルを誰かが示すことができますか? (関数名とクラス名) はどのようになりますか?
私はそれを突き刺します:
class A
{
int a;
void f(int, int);
};
記号「A」、「a」、および「f」を含む記号テーブルを生成します。通常、「a」と「f」は、ルックアップを簡素化するためのスコープでマークされます。次に例を示します。
"A" -> (class)
"A::a" -> (class variable member)
"A::f(int,int)" -> (class function member)
a
およびf
シンボルが最上位のシンボル テーブルに格納されず、各名前空間 (C++ の名前空間とクラスを含む) が独自のシンボル テーブルを持ち、内部で定義されたシンボルを含む可能性もあります。しかし、これは間違いなく、データ構造の選択にすぎません。シンボル テーブルを、名前が構造にマップされるフラット テーブルとして抽象的に表示することもできます。
一般に、"A::a" シンボルは、リンクには必要ないため、オブジェクト ファイルに出力されません。