Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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).

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.

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  
}
like image 508
Carlos Avatar asked Sep 03 '11 06:09

Carlos


People also ask

Are virtual functions statically bound or dynamically bound?

Non- virtual member functions are resolved statically. That is, the member function is selected statically (at compile-time) based on the type of the pointer (or reference) to the object. In contrast, virtual member functions are resolved dynamically (at run-time).

What is meant by static invocation of virtual function?

Virtual functions are invoked when you have a pointer or reference to an instance of a class. Static functions aren't tied to the instance of a class but they are tied to the class. C++ doesn't have pointers-to-class, so there is no scenario in which you could invoke a static function virtually.

How late binding is achieved using virtual function?

Using a Virtual Function In C++, late binding is achieved by inserting a virtual keyword preceding the declaration of the function in the base class. This informs the compiler that this function is designated for late binding.

Can virtual functions be static members?

A virtual function cannot be global or static because, by definition, a virtual function is a member function of a base class and relies on a specific object to determine which implementation of the function is called. You can declare a virtual function to be a friend of another class.


1 Answers

Obviously the compiler writers have not bothered to solve this case. Perhaps it is not common enough in real code to be worth their attention.

If GetACRef is defined elsewhere, it is also possible that C is polymorphic there, which could affect the optimizations.

Note that a compiler isn't solving every possible case where a small test program is "obvious" to a human. The compilers' focus is cases that happen often in large real programs.

like image 66
Bo Persson Avatar answered Oct 11 '22 14:10

Bo Persson