LTO,Devirtualization和虚拟表 [英] LTO, Devirtualization, and Virtual Tables

查看:302
本文介绍了LTO,Devirtualization和虚拟表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在比较C ++虚函数和虚拟表中的C,做编译器一般(和足够大的项目)在devirtualization做的一样好工作?

Comparing virtual functions in C++ and virtual tables in C, do compilers in general (and for sufficiently large projects) do as good a job at devirtualization?

天真,好像用C虚函数++有稍微的语义,从而可能会更容易devirtualize。

Naively, it seems like virtual functions in C++ have slightly more semantics, thus may be easier to devirtualize.

更新:的鸣叫鸭提到内联devirtualized功能。快速检查显示未接有虚表的优化:

Update: Mooing Duck mentioned inlining devirtualized functions. A quick check shows missed optimizations with virtual tables:

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不会直列楼虽然是直接调用,即devirtualized。在C ++中的等价,

My GCC will not inline f, although it is called directly, i.e., devirtualized. The equivalent in 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 ++版本增加的语义在这种情况下,相关的。

does even inline f. So there's a first difference between C and C++, although I don't think that the added semantics in the C++ version are relevant in this case.

更新2:的为了devirtualize中的 C 的,编译器必须证明在虚拟表中的函数指针具有一定的价值。为了能在 C ++来devirtualize 的,编译器必须证明的对象是特定类的一个实例。这似乎证明是在第一种情况下更难。但是,虚拟表通常改性只有极少数的地方,最重要的是:仅仅因为它看起来更难,并不意味着编译器不在它的好(否则你可能会认为,异或普遍较快比增加了两个整数)。

Update 2: In order to devirtualize in C, the compiler has to prove that the function pointer in the virtual table has a certain value. In order to devirtualize in C++, the compiler has to prove that the object is an instance of a particular class. It would seem that the proof is harder in the first case. However, virtual tables are typically modified in only very few places, and most importantly: just because it looks harder, doesn't mean that compilers aren't as good in it (for otherwise you might argue that xoring is generally faster than adding two integers).

推荐答案

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

The difference is that in C++, the compiler can guarantee that the virtual table address never changes. In C then it's just another pointer and you could wreak any kind of havoc with it.

但是,虚拟表中只有极少数的地方通常是修改

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

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

The compiler doesn't know that in C. In C++, it can assume that it never changes.

这篇关于LTO,Devirtualization和虚拟表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆