繁体   English   中英

什么时候编译器可以静态绑定对虚函数的调用?

[英]When can the compiler statically bind a call to a virtual function?

我期望编译器能够静态解析对函数的函数调用,如果类的类型在编译时是已知的(例如,如果没有通过引用或指针使用类实例,如案例1中所示)下面)。

但是,我观察到Visual Studio 2010的C ++编译器存在奇怪的行为,我想知道当虚拟类的实例时,编译器是否有任何理由不静态绑定对“正确”虚函数的调用函数是通过引用访问的结构中的成员。

我是否希望编译器在下面的案例2中静态绑定对f()的调用? cr的“参考”是否会以某种方式传播到cr.a,即使aA而不是A&

struct A
{
    virtual void f() ;
    virtual ~A() ;
};

struct B : A
{
    virtual void f() ;
    virtual ~B() ;
};

struct C {
    A a ;
    B b ;
};

C & GetACRef() ;

void test()
{
    // Case 1) The following calls to f() are statically bound i.e.
    // f() is called without looking up the virtual function ptr.
    C c ;  
    c.a.f() ;
    c.b.f() ;
    A a ;
    a.f() ;

    // Case 2) The following calls to f() go through the dynamic dispatching
    // virtual function lookup code. You can check if you generate the .asm
    // for this file.
    C & cr = GetACRef() ; // Note that C is not polymorphic
    cr.a.f() ; // visual C++ 2010 generates call to f using virtual dispatching
    cr.b.f() ; // visual C++ 2010 generates call to f using virtual dispatching  
}

显然,编译器编写者并不打算解决这种情况。 也许在实际代码中不值得他们注意。

如果在其他地方定义了GetACRef ,那么C也可能是多态的,这可能会影响优化。

请注意,编译器并未解决小型测试程序对人类“显而易见”的每种可能情况。 编译器的重点是经常在大型实际程序中发生的情况。

我不知道为什么MSVC不会将你的“案例2”场景编译成直接调用 - 这当然是可能的。 我认为只有微软才能回答。

请注意,GCC确实执行了您正在寻找的优化(使用MinGW 4.5.1和-O2进行测试)。

此外,MSVC甚至按以下顺序使用vtable调度(为清楚起见 - 我使用/Ox优化选项):

A a;
A& ar(a);
ar.f();

因此,不需要函数或容器结构来向编译器添加潜在的混淆层 - 编译器没有理由不能将ar.f()与该序列中的af()完全相同。 但正如Bo Persson所暗示的那样,也许这不是一个非常常见的优化方案(或者MS很明显没有得到它)​​。 同样,只有MS的编译器开发人员才能回答。

我不确定我会把这种行为归类为“奇怪” - 这是一个错过的优化机会。 我不确定这种事情有多常见。 在这种情况下,您是否希望编译器生成静态绑定调用? 也许。 但我认为不会发生这种情况并不太令人惊讶。

也许应该在MS Connect上打开一个问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM