2012-08-09 6 views
25

私はGDBのいくつかのC++コードをデバッグしていましたが、いくつかの呼び出しがいわゆる "合成ポインタ"を使用していることがわかりました。周りをグーグルで回っても意味のある結果は得られませんでした。ここでの検索では、タイトルに "synthetic"が付いているほとんどの質問は、Javaの一部の機能を参照しています(この文脈では、 "合成"は "人為的にコンパイラによって生成されたもの"を意味します)。合成ポインタとは何ですか?

例えば、このバックトレースを見て、一回の操作から取った、1人のクラスメンバー上、MyClassのコンストラクタで行う(このコードは、-O2とコンパイルされている)mと呼ば:

#0 MyClass (arg=..., this=<synthetic pointer>) at somefile.h:144 
144  m->lock(); 
gdb$ print this 
$1 = (MyClass * const) <synthetic pointer> 
gdb$ print *this 
$2 = <optimized out> 

上記スタックトレースthisは最適化されたオブジェクトへのポインタですが、メソッド(つまりそのコンストラクタ)が呼び出された可能性はありますか?私の推測では、囲まれたオブジェクト(m)がコード内で積極的に使用されていても、いくつかの最適化によってコンパイラは囲むオブジェクト(this)が本当に必要ではないと判断します。最適化することができないメソッド呼び出しm->lock()は、どこかで生成されなければならないので、コンパイラはメモリ内のどこにも置かれていない "fake"(合成?)オブジェクトを作成し、ただmをラップします。

私は強力なコンパイラの経験がないので、この結論が本当に意味をなさないかわかりません。誰かがこれにいくつかの光を当ててくださいか?

ありがとうございます。

答えて

12

コンパイラは、thisが実際に参照解除された(つまり、一般的なC++ルールではなく特定のCPUの詳細を使用している)かどうかを判断できます。メソッドが実際にthisを逆参照しない場合、phyiscal表現を使用する必要はありません。

[編集] コメントでは、jwwが別のケースを説明しました。シングルトンにはコピーが1つしかないので、スマートコンパイラはメンバをグローバルとして扱うことができます。つまり、singleton->fooのアドレスは、ちょうど定数である&singleton + offset(foo)です。この最適化の結果、シングルトンメソッドはシングルトンメンバへのアクセスを得るために実際にthisを参照解除する必要がないため、再度最適化することができます。

+0

はい、私の「MyClass」オブジェクトは構築され、参照されず、後で破壊されました。唯一の重要な操作は、コンストラクタ/デストラクタの副作用でした(レコードの場合は、スコープロックのカスタム実装です)。これは事実であるに違いありません。ありがとうございました。 –

+2

これは合成ポインターが実際に(「これ」が最適化されているとき)何ですか?私は、この答えは、オブジェクトが最適化される "this"のケースである "合成ポインター"ではなく、参照されていない場合に最適化されることが可能であるというサイドノートとして解釈できると感じています。私はスタックトレースの合成ポインタを見るので、それを通常のメッセージではないと解釈する方法がわかりません。 –

+2

@JoeyCarson:それはすべて哲学的です。正式には、オブジェクトは存在するか存在しません。オプティマイザが実行された後、オブザーバビリティプログラムに必要な程度にオブジェクトが部分的に存在する可能性があります。実際のオブジェクトを偽造するのはデバッガに任されています。それは科学ではありません。 – MSalters

関連する問題