virtual base offset in virtual function table for virtual inheritance
<p>The codes are as follows (C++11 codes compiled with G++-5.4 on Ubuntu 16.04):</p>

<pre><code>#include &lt;iostream&gt;

using namespace std;



class Base
{
    public:
        virtual void show()
        {
            cout &lt;&lt; "Base" &lt;&lt; endl;
        }

        virtual void func()
        {
            cout &lt;&lt; "func in Base" &lt;&lt; endl;
        }

    protected:
        int base = 15;
};

class A: public virtual Base
{
    public:
        void show() override
        {
            cout &lt;&lt; this &lt;&lt; endl;
            cout &lt;&lt; 'A' &lt;&lt; endl;
        }

        void func() override
        {
            cout &lt;&lt; this &lt;&lt; endl;
            cout &lt;&lt; "func in A" &lt;&lt; endl;
        }

    protected:
        int a = 31;
};



int main(int argc, const char *argv[])
{
    A obj_a;

    return 0;
}
</code></pre>

<p>I try to use GDB to check memory layout of object "obj_a" (firstly, I set "set print object on", "set print pretty on", "set print vtbl on", "set print asm-demangle on" in GDB):</p>

<pre><code>(gdb) p sizeof(obj_a)
$1 = 32
(gdb) x/8aw &amp;obj_a
0x7fffffffe320: 0x400d20 &lt;vtable for A+24&gt;  0x0 0x1f    0x0
0x7fffffffe330: 0x400d50 &lt;vtable for A+72&gt;  0x0 0xf 0x0
</code></pre>

<p>We can know that the offset between the beginning of obj_a and its virtual base subobject is 16B (virtual base offset). And then I check A's virtual function table pointed by <strong>0x400d08</strong> (0x400d20 - 24):</p>

<pre><code>(gdb) x/14ag 0x400d08
0x400d08 &lt;vtable for A&gt;:    0x10    0x0
0x400d18 &lt;vtable for A+16&gt;: 0x400d90 &lt;typeinfo for A&gt;   0x400b46 &lt;A::show()&gt;
0x400d28 &lt;vtable for A+32&gt;: 0x400b98 &lt;A::func()&gt;    0xfffffffffffffff0
0x400d38 &lt;vtable for A+48&gt;: 0xfffffffffffffff0  0xfffffffffffffff0
0x400d48 &lt;vtable for A+64&gt;: 0x400d90 &lt;typeinfo for A&gt;   0x400b8f &lt;virtual thunk to A::show()&gt;
0x400d58 &lt;vtable for A+80&gt;: 0x400be1 &lt;virtual thunk to A::func()&gt;          0x400d20 &lt;vtable for A+24&gt;
0x400d68 &lt;VTT for A+8&gt;: 0x400d50 &lt;vtable for A+72&gt;  0x0
</code></pre>

<p>As we can see, there are two "virtual thunk to xxx", namely "0x400b8f " and "0x400be1 ". I peer into these two addresses.</p>

<pre><code>(gdb) x/3i 0x400b8f
0x400b8f &lt;virtual thunk to A::show()&gt;:  mov    (%rdi),%r10
0x400b92 &lt;virtual thunk to A::show()+3&gt;:    add    -0x18(%r10),%rdi
0x400b96 &lt;virtual thunk to A::show()+7&gt;:    jmp    0x400b46 &lt;A::show()&gt;
(gdb) x/3i 0x400be1
0x400be1 &lt;virtual thunk to A::func()&gt;:  mov    (%rdi),%r10
0x400be4 &lt;virtual thunk to A::func()+3&gt;:    add    -0x20(%r10),%rdi
0x400be8 &lt;virtual thunk to A::func()+7&gt;:    jmp    0x400b98 &lt;A::func()&gt;
</code></pre>

<p>My questions are: what do "add    -0x18(%r10),%rdi" and "add    -0x20(%r10),%rdi" really mean? why are -24 (-0x18) and -32 (-0x20)? (I think they should all be -16)</p>