gpt4 book ai didi

c++ - LTO、去虚拟化和虚拟表

转载 作者:IT老高 更新时间:2023-10-28 22:27:57 28 4
gpt4 key购买 nike

比较 C++ 中的虚函数和 C 中的虚表,编译器在一般情况下(以及对于足够大的项目)在去虚拟化方面是否同样出色?

天真地,C++ 中的虚函数似乎具有更多的语义,因此可能更容易去虚拟化。

更新: Mooing Duck 提到了内联去虚拟化函数。快速检查显示虚拟表错过的优化:

struct vtab {
int (*f)();
};

struct obj {
struct vtab *vtab;
int data;
};

int f()
{
return 5;
}

int main()
{
struct vtab vtab = {f};
struct obj obj = {&vtab, 10};

printf("%d\n", obj.vtab->f());
}

我的 GCC 不会内联 f,尽管它是直接调用的,即去虚拟化的。 C++ 中的等价物,

class A
{
public:
virtual int f() = 0;
};

class B
{
public:
int f() {return 5;}
};

int main()
{
B b;
printf("%d\n", b.f());
}

甚至内联 f。因此,C 和 C++ 之间存在第一个区别,尽管我认为 C++ 版本中添加的语义与这种情况无关。

更新2:为了在C中去虚拟化,编译器必须证明虚表中的函数指针具有一定的值。为了在 C++ 中去虚拟化,编译器必须证明对象是特定类的实例。在第一种情况下,证明似乎更难。然而,虚拟表通常只在很少的地方被修改,最重要的是:仅仅因为它看起来更难,并不意味着编译器在它上面没有那么好(否则你可能会争辩说 xoring 通常比添加两个更快整数)。

最佳答案

不同的是,在C++中,编译器可以保证虚拟表地址永远不会改变。在 C 中,它只是另一个指针,你可以对它造成任何破坏。

However, virtual tables are typically modified in only very few places

编译器在 C 中不知道。在 C++ 中,它可以假设它永远不会改变。

关于c++ - LTO、去虚拟化和虚拟表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7046739/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com