Within the following code, it calls an online function foo using a pointer to some derived object. Will this call feel the vtable or does it call B::foo directly?

Whether it goes using a vtable, what will be a C++ idiomatic method of which makes it call B::foo directly? (I understand that within this situation I'm always pointing to some B)


Class A

        virtual void foo() {}

class B : public A
        virtual void foo() {}

int main()
    B* b = new B();

Most compilers is going to be wise enough to get rid of the indirect call for the reason that scenario, for those who have optimisation enabled. Only since you just produced the item and also the compiler knows the dynamic type there might be situations when you are aware the dynamic type and also the compiler does not.

As always, the response to this is "if you should you, have a look in the released code". This is exactly what g++ produces without any optimisations selected:

18     b->foo();
0x401375 <main+49>:  mov    eax,DWORD PTR [esp+28]
0x401379 <main+53>:  mov    eax,DWORD PTR [eax]
0x40137b <main+55>:  mov    edx,DWORD PTR [eax]
0x40137d <main+57>:  mov    eax,DWORD PTR [esp+28]
0x401381 <main+61>:  mov    DWORD PTR [esp],eax
0x401384 <main+64>:  call   edx

that is while using vtable. An immediate call, created by code like:

B b;

appears like this:

0x401392 <main+78>:  lea    eax,[esp+24]
0x401396 <main+82>:  mov    DWORD PTR [esp],eax
0x401399 <main+85>:  call   0x40b2d4 <_ZN1B3fooEv>

Yes, it'll make use of the vtable (only non-virtual techniques bypass the vtable). To call B::foo() on b directly, call b->B::foo().

Compiler can optimize away virtual dispatch and call virtual function directly or inline it whether it can be it is the same behavior. Within the provided example, compiler will easily discard every type of code, so that all you will get is:

int main() {}

This is actually the put together code from g++ (4.5) with -O3


    subq    $8, %rsp
    movl    $8, %edi
    call    _Znwm
    movq    $_ZTV1B+16, (%rax)
    movq    %rax, %rdi
    call    *_ZTV1B+16(%rip)
    xorl    %eax, %eax
    addq    $8, %rsp

    .quad   0
    .quad   _ZTI1B
    .quad   _ZN1B3fooEv

The only real optimisation it did was it understood which vtable to make use of (around the b object). Otherwise "call *_ZTV1B+16(%rip)" could have been "movq (%rax), %rax call *(%rax)". So g++ is really quite bad at optimizing virtual function calls.