غير LLVM استثناء لهذه القاعدة لتجنب يلقي الديناميكية؟
-
05-07-2019 - |
سؤال
وLLVM لها انها اليد الخاصة توالت بديل لRTTI الذي هو تحسين سرعة أكثر من المدمج في RTTI ويسمح الصب الديناميكي إلى الطبقات مع عدم وجود vtable (dyn_cast
). ومع ذلك، فإنه لا يزال من الممكن استخدامها في بنفس الطريقة التي dynamic_cast<>
يستخدم على الرغم من أنه لا يسمح لاستخدامها مع مزيد من الدراسة.
وLLVM هو مشروع السمعة C ++ لذلك هذا يبدو أن يطير في مواجهة نزلات قائلا أن الكثير من قوالب ديناميكية هو علامة على تصميم سيئة، والمعروف أيضا رائحة التعليمات البرمجية. بالتأكيد يلقي ديناميكية أداء أفضل لا يفعل شيئا لتحسين استخدامه في التصميم من dynamic_cast
المعيار. فمن هو هنا؟ هل هناك حالات حيث استخدام على نطاق واسع من صب الديناميكي هو اختيار التصميم الجيد في التعليمات البرمجية C ++؟ جوجل حتى تتحول 690 حوادث من هذا النوع من صب ديناميكية في LLVM شفرة المصدر الجذع.
المحلول
وحين يضرب الأداء هي سبب لتجنب dynamic_cast<>
التسلسلات الهرمية فئة كبيرة، انها ليست السبب الوحيد الذي قد ترغب في تجنبها. أداء أفضل أم لا، ينبغي للمرء أن لا يكون أكثر تشجيعهم على استخدام dyn_cast<>
بسبب هذا الادعاء.
وعلى الجانب الآخر، هناك شيء على الاطلاق بأس باستعمال dynamic_cast<>
عندما يكون أفضل وسيلة للحصول على الوظيفة. إذا استعماله لها ما يبررها، وأنظف طريقة لحل المشكلة، ثم انها دائما على حق، بغض النظر عن "القول الشائع".
وأنا بالتأكيد لن تبتعد عن مشاريع شعبية ببساطة لأنها تستخدم dynamic_cast<>
s، goto
s أو أي لغة الآخر الذي سقط من صالح.
نصائح أخرى
وأعتقد ديناميات يلقي سيئة ليس لأنهم بطيئة، ولكن لأنها تعني أن التعليمات البرمجية يقترن محكم جدا.
ولقد اتخذت فقط نظرة سريعة للغاية في تنفيذ dyn_cast وعيسى في وثائق LLVM.
ووحصول exmaple في رمز له ما يلي:
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
إلى شريط الارتباطات مع فو. في الأمثلة الواردة يبدو أن isa<foo>(B1)
يعود صحيحا!
وعلى أي حال، وهذا هو السلوك مختلفة جدا لتلك التي dynamic_cast، لذلك أنا حقا لا أعتقد أنك يمكن مقارنتها ضد بعضها البعض.
من الواضح، قد أكون سوء فهم ما تقوم به LLVM، لذلك اسمحوا لي أن أعرف إذا كنت لم يفهم رمز!