LLVM 是避免动态强制转换规则的例外吗?

发布于 2024-08-09 02:47:21 字数 672 浏览 7 评论 0原文

LLVM 有自己的 RTTI 手动替代方案,它比内置 RTTI 速度有所提高,并且允许动态转换为没有 vtable 的类 (dyn_cast)。然而,它仍然可以完全按照 dynamic_cast 的使用方式使用,尽管它确实允许它与更多类一起使用。

dyn_cast 模板文档

LLVM 是一个信誉良好的 C++ 项目因此,这似乎违背了俗话说,太多的动态转换是糟糕设计的标志,也称为代码异味。当然,与标准dynamic_cast相比,性能更好的动态转换并不能改善其在设计中的使用。那么谁在这里呢?在某些情况下,大规模使用动态转换是否是 C++ 代码中良好的设计选择? Google 在 LLVM 主干源代码中发现了 690 次此类动态转换。

使用LLVM 主干中的dyn_cast<>

LLVM has it's own hand rolled alternative to RTTI that is a speed improvement over built-in RTTI and allows dynamic casting to classes with no vtable (dyn_cast). However, it can still be used in exactly the way that dynamic_cast<> is used though it does allow it to be used with more classes.

dyn_cast<> template documentation

LLVM is a reputable C++ project so this seems to fly in the face of the common saying that too many dynamic casts is a sign of bad design, also known as a code smell. Surely a better performing dynamic cast does nothing to improve its use in design than a standard dynamic_cast. So who is right here? Are there cases where large-scale use of dynamic casting is a good design choice in C++ code? Google turns up 690 occurrences of this kind of dynamic casting in the LLVM trunk source code.

Uses of dyn_cast<> in LLVM trunk

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

为人所爱 2024-08-16 02:47:21

虽然性能影响是大型类层次结构避免使用 dynamic_cast<> 的一个原因,但这并不是您想要避免它们的唯一原因。无论性能如何,都不应该因为这一说法而更加鼓励使用 dyn_cast。

另一方面,当dynamic_cast是最适合这项工作的工具时,使用它绝对没有任何问题。如果它的使用是合理的,并且是解决问题的最干净的方法,那么它总是正确的,无论“俗话说”如何。

我当然不会仅仅因为流行的项目使用 dynamic_cast<>goto 或任何其他不受欢迎的习惯用法而避开它们。

While performance hits are a reason to avoid dynamic_cast<> for large class hierarchies, it's not the only reason you might want to avoid them. Better performing or not, one should not be more encouraged to use dyn_cast<> because of this claim.

On the other hand, there's absolutely nothing wrong with using dynamic_cast<> when it's the best tool for the job. If its use is justified, and the cleanest way to solve a problem, then it's always right, regardless of the "common saying".

I would certainly not steer clear of popular projects simply because they use dynamic_cast<>s, gotos or any other idiom that's fallen out of favour.

拔了角的鹿 2024-08-16 02:47:21

我认为动态转换不好不是因为它们很慢,而是因为它们意味着您的代码耦合得太紧密。

I think dynamics casts are bad not because they are slow, but because they imply that your code is too tightly coupled.

泅人 2024-08-16 02:47:21

我只是快速浏览了 LLVM 文档中 dyn_cast 和 isa 的实现。

代码中的 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 模板(由 < code>dyn_cast) 使用 isa_impl 的显式特化将 bar 与 foo 链接起来。在给出的示例中,似乎 isa(B1) 返回 true!

不管怎样,这与dynamic_cast 的行为非常不同,所以我真的不认为你可以将它们相互比较。

显然,我可能误解了 LLVM 在做什么,所以如果我不理解代码,请告诉我!

I've only taken a very quick look at the implementation of dyn_cast and isa in the LLVM documentation.

The exmaple in the code has the following:

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;
}

The test is called with a B and has:

if (!isa<foo>(B1)) return;
if (!isa<foo>(B2)) return;

If I understand what's going on correctly, the isa template (which is used by dyn_cast) uses the explicit specialization of isa_impl to link bar with foo. In the examples given it seems that isa<foo>(B1) returns true!

Anyway, this is very different behaviour to that of dynamic_cast, so I really don't think you can compare them against each other.

Obviously, I may be mis-understanding what LLVM is doing, so please let me know if I've not understood the code!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文