LLVMは動的キャストを回避するための規則の例外ですか?
-
05-07-2019 - |
質問
LLVMには、RTTIに代わる独自の手動ロール代替機能があります。これは、組み込みRTTIよりも速度が向上し、vtable(dyn_cast
)のないクラスへの動的なキャストを可能にします。ただし、dynamic_cast<>
を使用する方法とまったく同じように使用できますが、より多くのクラスで使用することはできます。
LLVMは評判の良いC ++プロジェクトであるため、あまりにも多くのダイナミックキャストはデザインの悪さの兆候であり、コードスメルとも呼ばれるという一般的な言い方に直面しているようです。確かにパフォーマンスの良い動的キャストは、標準のdynamic_cast
よりもデザインでの使用を改善するものではありません。誰がここにいるの? C ++コードで、動的キャストの大規模な使用が適切な設計選択である場合はありますか? Googleは、LLVMトランクのソースコードでこの種の動的なキャストの690回の出現を検出しました。
解決
パフォーマンスのヒットは、大規模なクラス階層ではdynamic_cast<>
を回避する理由ですが、回避する必要があるのはそれだけではありません。パフォーマンスが良くても悪くても、この主張のためにdyn_cast<>
を使用することは推奨されません。
一方で、goto
が仕事に最適なツールである場合、<=>を使用してもまったく問題はありません。その使用が正当化され、問題を解決する最もクリーンな方法であれば、<!> quot; common say <!> quot;。
<=> s、<=> s、または好意から外れた他のイディオムを使用しているという理由だけで、私は確かに人気のあるプロジェクトを避けません。
他のヒント
ダイナミクスキャストは遅いからではなく、コードが密に結合されていることを意味するため、悪いと思います。
LLVMのドキュメントでdyn_castとisaの実装を非常に簡単に見てきました。
コードの例には次のものがあります。
struct bar {
bar() {}
private:
bar(const bar &);
};
struct foo {
void ext() const;
/* static bool classof(const bar *X) {
cerr << "Classof: " << X << "\n";
return true;
}*/
};
template <> inline bool isa_impl<foo,bar>(const bar &Val) {
errs() << "Classof: " << &Val << "\n";
return true;
}
テストはB
で呼び出され、次のものがあります。
if (!isa<foo>(B1)) return;
if (!isa<foo>(B2)) return;
何が正しく行われているのか理解している場合、isa
テンプレート(dyn_cast
で使用)は、isa_impl
の明示的な特殊化を使用してbarとfooをリンクします。与えられた例では、isa<foo>(B1)
はtrueを返しているようです!
とにかく、これはdynamic_castの動作とは非常に異なる動作なので、それらを互いに比較できるとは本当に思いません。
明らかに、LLVMが何をしているのかを誤解している可能性があるため、コードを理解していない場合はお知らせください!