6

C++ コードのシンボル テーブルに関数名とクラス名が含まれているかどうかについて、さまざまな投稿を検索してきました。投稿で見つけたのは、コンパイラのタイプに依存するということです。

ワンパスでコードをコンパイルする場合、シンボル テーブルにクラス名とサブルーチン名を格納する必要はありません。

ただし、マルチパス コンパイラの場合は、検出したクラスとそのサブルーチンに関する情報を追加して、引数の型チェックを実行し、意味のあるエラー メッセージを発行できます。

実際にコンパイラに依存しているかどうかを理解できませんでしたか? 私は、コンパイラー (C++ コードの場合) が、シングルパスコンパイラーであろうとマルチパスコンパイラーであろうと、関数名とクラス名をテーブルに入れると想定していました。パスにどのように依存していますか?私はそのような素晴らしい/深い知識を持っていません。さらに、単純な C++ クラスのサンプル シンボル テーブルを誰かが示すことができますか? (関数名とクラス名) はどのようになりますか?

4

3 に答える 3

2

シンボル テーブルは、名前をプログラム内の構造にマップします。そのため、クラス、関数、変数、およびプログラム内でユーザーが指定した名前を持つその他すべての名前を記録するために使用されます。

(シンボル テーブルには 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" シンボルは、リンクには必要ないため、オブジェクト ファイルに出力されません。

于 2015-08-14T14:15:20.260 に答える
0

簡単な答え: はい、Linux で「nm --demangle」を使用します

長い答え: シンボル テーブルの関数には、関数名と戻り値が含まれており、クラスに属している場合はクラス名も含まれています。ただし、名前、型 (常にではありません)、およびクラスは、使用するスペースを少なくするために完全な名前で書かれているわけではありません。デマングルと呼ばれるこの弦。しかし、この短縮名は固有のものであり、そこから完全なクラス名を解析できることがわかっています。プログラムのシンボル テーブルを表示するには、Linux で「nm」を使用できます。

http://linux.about.com/library/cmd/blcmdl1_nm.htm

元の名前を表示する --demangle フラグを取得しました。ランダムな短いプログラムをコンパイルして、何が出るかを確認できます。

于 2015-08-14T14:19:36.873 に答える