什么时候编译器可以静态绑定对虚函数的调用? [英] When can the compiler statically bind a call to a virtual function?

查看:129
本文介绍了什么时候编译器可以静态绑定对虚函数的调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望编译器能够静态解析一个函数调用虚函数,如果类的类型在编译时已知(例如,如果类实例没有通过引用或指针使用,如图所示情况1))。

I expected the compiler to be able to statically resolve a function call to a virtual function if the type of the class is known at compile time (e.g. if the class instance is not being used through a reference or a pointer as illustrated in Case 1) below).

但是,我发现Visual Studio 2010的C ++编译器有一个奇怪的行为,我想知道是否有任何原因编译器不静态绑定调用

However, I have observed a strange behavior with Visual Studio 2010's C++ compiler and I would like to know if there is any reason for the compiler not to statically bind the calls to the "right" virtual function when the instances of the classes with the virtual functions are members in a structure that is being accessed by reference.

如果我希望编译器静态的话,那么虚拟函数绑定调用f()在case 2)下面?即使 a A 而不是,cr的引用 code> A&

Should I expect the compiler to statically bind the calls to f() in Case 2) below? Is the "reference"ness of cr somehow propagating to cr.a even though a is an A and not an 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  
}


推荐答案

我不知道为什么MSVC不编译你的情况2场景直接调用 - 这当然是可能的。我认为只有微软能够回答。

I don't know why MSVC doesn't compile your "Case 2" scenarios to direct calls - it's certainly possible. I think that only Microsoft would be able to answer.

请注意,GCC会执行您正在寻找的优化(使用MinGW 4.5.1和<$ c

Note that GCC does perform the optimization that you're looking for (tested with MinGW 4.5.1 and -O2).

此外,MSVC使用vtable dispatch即使对于以下序列(为了清楚起见 - 我使用 / Ox 优化选项):

Also, MSVC used vtable dispatch even for the following sequence (for clarity - I'm using the /Ox optimization option):

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

因此,没有必要使用函数或容器结构来向编译器添加潜在的混淆没有理由编译器不能在该序列中处理与 af()完全相同的 ar.f()但正如Bo Persson建议的,也许这不是一个非常常见的优化方案(或MS只是平淡没有得到它)​​。再次,只有MS的编译器开发人员可以回答。

So there's no need for a function or container struct to add layers of potential confusion to the compiler - there's no reason the compiler can't treat ar.f() exactly the same as a.f() in that sequence. But as Bo Persson has suggested, perhaps it's not an extremely common optimization scenario (or MS have just plain not gotten around to it). Again, only the compiler devs at MS could answer.

我不知道我会把这个行为归类为'奇怪' - 这是一个优化机会,所有。我不知道这种事可能有多常见。你应该期望编译器在这种情况下生成静态绑定调用吗?也许。

I'm not sure I'd classify this behavior as 'strange' though - it's an optimization opportunity that's missed is all. I'm not sure how common this kind of thing might be. Should you expect the compiler to generate statically bound calls in this case? Maybe. But I think it's not too surprising that it doesn't happen.

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

Maybe an issue should be opened on MS Connect.

这篇关于什么时候编译器可以静态绑定对虚函数的调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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