Part 1: All About Virtual Keyword in C++: How Does Virtual Function Works Internally?
Tags: cpp, programming, tutorial, computerscience
Published: 2020-05-20 13:31:37

<!-- wp:paragraph -->
<p>"All About Virtual Keyword in C++" is a series of articles(total of three, <a rel="noreferrer noopener" aria-label="PART 1 (opens in a new tab)" href="http://www.vishalchovatiya.com/part-1-all-about-virtual-keyword-in-cpp-how-virtual-function-works-internally/" target="_blank"><span style="color:#1409f5" class="color">PART 1</span></a>, <a rel="noreferrer noopener" aria-label="PART 2 (opens in a new tab)" href="http://www.vishalchovatiya.com/part-2-all-about-virtual-keyword-in-cpp-how-virtual-class-works-internally/" target="_blank"><span style="color:#0616eb" class="color">PART 2</span></a>, <a rel="noreferrer noopener" aria-label="PART 3 (opens in a new tab)" href="http://www.vishalchovatiya.com/part-3-all-about-virtual-keyword-in-c-how-virtual-destructor-works/" target="_blank"><span style="color:#061df2" class="color">PART 3</span></a>) describe working of the virtual keyword in different scenarios. This article mostly focuses on "How Does Virtual Function Works Internally?". In other words, How dynamic dispatch done in C++! Although I am not a compiler writer, but this is what I have learned so far from various sources, courses, books &amp; disassembly of C++ program. </p>
<!-- /wp:paragraph -->


> /!\\\: Originally published @ [www.vishalchovatiya.com](http://www.vishalchovatiya.com/).

<!-- wp:paragraph -->
<p>Before diving into the How virtual function works internally!, I would like to clarify two things</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><li>Implementation of dynamic dispatch(i.e. virtual function) is purely compiler dependent.</li><li>C++ standard does not define the implementation. It only states the behaviour.</li></ol>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>I always ask my self before learning anything new "Why do we need it in the first place?". So, let's start there:</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>Why Do We Need a Virtual Function?</h2>
<!-- /wp:heading -->

<!-- wp:list -->
<ul><li>Let's understand it with an example. Suppose you want to connect to the network or to other mobile using your smartphone.</li><li>So, you have two choices Bluetooth or Wifi. Although these two are completely different technologies, still some things are common in them at an abstract/behavioural level like both are communication protocol, both need authentication, etc.</li><li>For example, we have a class of them as follows:</li></ul>
<!-- /wp:list -->

```c++
class wifi_t{
    private:
        char _pass[15];
        // storage ...
    public:
        void authenticate();
        void connect();
        // operations ...
};
class bluetooth_t{
    private:
        char _pass[15];
        // storage ...
    public:
        void authenticate();
        void connect();
        // operations ...
};
```

<!-- wp:list -->
<ul><li>Now, below is the main application in which you want to connect your device to others.</li></ul>
<!-- /wp:list -->

```c++
int main()
{
    wifi_t          *wifi = new wifi_t;
    bluetooth_t     *bluetooth = new bluetooth_t;

    int pt = selectProtocol();

    if(pt == BLUETOOTH){
        bluetooth->authenticate();
        bluetooth->connect();
    }
    else if(pt == WIFI){
        wifi->authenticate();
        wifi->connect();
    }
    return 0;
}
```

<!-- wp:list -->
<ul><li>If you observe above code then you will find that despite selecting any protocol some steps are the same.</li><li>In such case, you can leverage virtual functions of C++ as follows:</li></ul>
<!-- /wp:list -->

```c++
class protocol_t{
    private:
        uint8_t _type;
        // storage ...
    public:
        virtual void authenticate(){};
        virtual void connect(){};
        // operations ...
};

class wifi_t : public protocol_t{
    private:
        char _pass[15];
        // storage ...
    public:
        virtual void authenticate(){};
        virtual void connect(){};
        // operations ...
};

class bluetooth_t : public protocol_t{
    private:
        char _pass[15];
        // storage ...
    public:
        virtual void authenticate(){};
        virtual void connect(){};
        // operations ...
};

void makeConnection(protocol_t *protocol)
{
    protocol->authenticate();
    protocol->connect();
}    

int main()
{
    int pt = selectProtocol();

    // You can not compile this line, but i have kept it that way for simplicity
    makeConnection( (pt == WIFI) ? new wifi_t : new bluetooth_t);

    return 0;
}
```
<!-- wp:paragraph -->
<p>Following are the benefits we have achieved through virtual keywords:</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><li><strong>Run time polymorphism</strong>: Behavioural functions identified automatically at runtime &amp; would called by their type like if <code>protocol</code> is wifi then execute <code>wifi_t::authenticate()</code> &amp; <code>wifi_t::connect()</code>.</li><li><strong>Reusability of code</strong>: Observe <code>makeConnection</code> function there is an only single call to behavioural functions we have removed the redundant code from main.</li><li><strong>Code would be compact</strong>: Observe earlier <code>main</code> function &amp; newer one.</li></ol>
<!-- /wp:list -->

<!-- wp:heading -->
<h2>How Does Virtual Function Works Internally?</h2>
<!-- /wp:heading -->

<!-- wp:list -->
<ul><li>When you declare any function virtual, the compiler will transform(augment is the precise word here) some of your code at compile time.</li><li>For instance, in our case class <code>protocol_t</code> the class object will be augmented by a pointer called <code>_vptr</code> which points to the virtual table.</li><li>In other words, this is nothing but a pointer(<code>_vptr</code>) which points to an array of a function pointer. That includes offset/address of your virtual functions. So that it can call your function through that table rather than calling it directly.</li></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>So if you call the function <code>authenticate()</code> using a pointer of type <code>protocol_t</code>  as below:</p>
<!-- /wp:paragraph -->

```c++
protocol_t *protocol;
// .... Assignment to `protocol`

protocol->authenticate();
```
<!-- wp:paragraph -->
<p>then it would probably augmented by a compiler like this</p>
<!-- /wp:paragraph -->

```c++
(*protocol->vptr[ 1 ])( protocol ); 
```

<!-- wp:paragraph -->
<p>Where the following holds:</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><li><code>_vptr</code> represents the internally generated virtual table pointer inserted within each object whose class<br>declares or inherits one or more virtual functions. In practice, its name mangled. There may be multiple _vptrs within a complex class derivation.</li><li>1 in _vptr[ 1 ] is the index into the virtual table slot associated with <code>authenticate()</code>. This index is decided by compiler &amp; fixed throughout the inheritance tree.</li><li><code>protocol</code> in its second occurrence(i.e. in the argument) represents the <code>this</code> pointer.</li></ol>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>When we inherit <code>wifi_t</code> class from <code>protocol_t</code> class, a new virtual table will be created by the compiler with overridden polymorphic function slot. Each virtual function has a fixed index in the virtual table, no matter how long the inheritance hierarchy is.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If <code>derived</code> class introduce a new virtual function not present in the base class, the virtual table will be grown by a slot and the address of the function is placed within that slot.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If you want to summarize virtual keyword functionality in two words then its <code>indirect calling</code> of a polymorphic function. And to visualize virtual function footprint you can take a look at my earlier article <a rel="noreferrer noopener" aria-label="memory layout of a C++ object (opens in a new tab)" href="http://www.vishalchovatiya.com/memory-layout-of-cpp-object/" target="_blank"><span style="color:#0007a3" class="color">memory layout of a C++ object</span></a>.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>Let's Address Some of the FAQs Around Virtual Function &amp; Virtual Table</h3>
<!-- /wp:heading -->

<!-- wp:yoast/faq-block {"questions":[{"id":"faq-question-1587279527773","question":["Q. Is virtual table per object or per class?"],"answer":["- This usually depends on compiler implementation. ",{"type":"br","props":{"children":[]}},"- But Generally, a",{"type":"strong","props":{"children":[{"type":"em","props":{"children":[" virtual table is per class"]}}]}}," and the",{"type":"strong","props":{"children":[{"type":"em","props":{"children":[" virtual table pointers(",{"type":"code","props":{"children":["_vptr"]}},") is to object"]}}]}},".",{"type":"br","props":{"children":[]}},"- There might be more than one virtual table pointers too depending upon type of inheritance."],"jsonQuestion":"Q. Is virtual table per object or per class?","jsonAnswer":"- This usually depends on compiler implementation. \u003cbr/\u003e- But Generally, a\u003cstrong\u003e\u003cem\u003e virtual table is per class\u003c/em\u003e\u003c/strong\u003e and the\u003cstrong\u003e\u003cem\u003e virtual table pointers(\u003ccode\u003e_vptr\u003c/code\u003e) is to object\u003c/em\u003e\u003c/strong\u003e.\u003cbr/\u003e- There might be more than one virtual table pointers too depending upon type of inheritance."},{"id":"faq-question-1587279506509","question":["Q. Where \u0026 how does virtual table/pointer code augments by the compiler?"],"answer":["- The code necessary to fill/override virtual table slot generated by the compiler at the time of compilation. To reiterate it in short, the ",{"type":"strong","props":{"children":[{"type":"em","props":{"children":["virtual table is generated statically at the compile time"]}}]}}," by the compiler.",{"type":"br","props":{"children":[]}}," in constructors right before user-written code.",{"type":"br","props":{"children":[]}},"- Virtual table pointer(i.e. ",{"type":"code","props":{"children":["_vptr"]}},") has fixed offset. And the ",{"type":"strong","props":{"children":[{"type":"em","props":{"children":["code to override "]}}]}},{"type":"code","props":{"children":[{"type":"em","props":{"children":[{"type":"strong","props":{"children":["_vptr"]}}]}}]}},{"type":"strong","props":{"children":[{"type":"em","props":{"children":[" is generated at the time of object construction"]}}]}}," by the compiler.",{"type":"br","props":{"children":[]}},"- This is the reason that you should not call the virtual function in constructor. Read more about it ",{"type":"a","props":{"rel":"noreferrer noopener","href":"https://stackoverflow.com/questions/962132/calling-virtual-functions-inside-constructors","target":"_blank","children":[{"type":"span","props":{"style":"color:#332ada","class":"color","children":["here"]}}]}},"."],"jsonQuestion":"Q. Where \u0026amp; how does virtual table/pointer code augments by the compiler?","jsonAnswer":"- The code necessary to fill/override virtual table slot generated by the compiler at the time of compilation. To reiterate it in short, the \u003cstrong\u003e\u003cem\u003evirtual table is generated statically at the compile time\u003c/em\u003e\u003c/strong\u003e by the compiler.\u003cbr/\u003e in constructors right before user-written code.\u003cbr/\u003e- Virtual table pointer(i.e. \u003ccode\u003e_vptr\u003c/code\u003e) has fixed offset. And the \u003cstrong\u003e\u003cem\u003ecode to override \u003c/em\u003e\u003c/strong\u003e\u003ccode\u003e\u003cem\u003e\u003cstrong\u003e_vptr\u003c/strong\u003e\u003c/em\u003e\u003c/code\u003e\u003cstrong\u003e\u003cem\u003e is generated at the time of object construction\u003c/em\u003e\u003c/strong\u003e by the compiler.\u003cbr/\u003e- This is the reason that you should not call the virtual function in constructor. Read more about it \u003ca rel=\u0022noreferrer noopener\u0022 href=\u0022https://stackoverflow.com/questions/962132/calling-virtual-functions-inside-constructors\u0022 target=\u0022_blank\u0022\u003e\u003cspan style=\u0022color:#332ada\u0022 class=\u0022color\u0022\u003ehere\u003c/span\u003e\u003c/a\u003e."},{"id":"faq-question-1587279471470","question":["Q. How do we know at runtime that pointer ",{"type":"code","props":{"children":["protocol"]}}," will execute a right function(of the object pointed to)?"],"answer":["- In general, we don't know the exact type of the object ",{"type":"code","props":{"children":["protocol"]}}," addresses at each invocation of ",{"type":"code","props":{"children":["authenticate()"]}},". However, we do know the virtual table pointer(",{"type":"code","props":{"children":["_vptr"]}},") offset(which is fixed) associated with the object's class. ",{"type":"br","props":{"children":[]}},"- And using this ",{"type":"code","props":{"children":["_vptr"]}},", we can access the virtual table of the object pointed by ",{"type":"code","props":{"children":["protocol"]}}," pointer. Again the index of function ",{"type":"code","props":{"children":["authenticate()"]}}," in a virtual table fixed throughout the inheritance hierarchy. This way right ",{"type":"code","props":{"children":["authenticate()"]}}," function execution guaranteed."],"jsonQuestion":"Q. How do we know at runtime that pointer \u003ccode\u003eprotocol\u003c/code\u003e will execute a right function(of the object pointed to)?","jsonAnswer":"- In general, we don't know the exact type of the object \u003ccode\u003eprotocol\u003c/code\u003e addresses at each invocation of \u003ccode\u003eauthenticate()\u003c/code\u003e. However, we do know the virtual table pointer(\u003ccode\u003e_vptr\u003c/code\u003e) offset(which is fixed) associated with the object's class. \u003cbr/\u003e- And using this \u003ccode\u003e_vptr\u003c/code\u003e, we can access the virtual table of the object pointed by \u003ccode\u003eprotocol\u003c/code\u003e pointer. Again the index of function \u003ccode\u003eauthenticate()\u003c/code\u003e in a virtual table fixed throughout the inheritance hierarchy. This way right \u003ccode\u003eauthenticate()\u003c/code\u003e function execution guaranteed."}]} -->
<div class="schema-faq wp-block-yoast-faq-block"><div class="schema-faq-section" id="faq-question-1587279527773"><strong class="schema-faq-question">Q. Is virtual table per object or per class?</strong> <p class="schema-faq-answer">- This usually depends on compiler implementation. <br/>- But Generally, a<strong><em> virtual table is per class</em></strong> and the<strong><em> virtual table pointers(<code>_vptr</code>) is to object</em></strong>.<br/>- There might be more than one virtual table pointers too depending upon type of inheritance.</p> </div> <div class="schema-faq-section" id="faq-question-1587279506509"><strong class="schema-faq-question">Q. Where &amp; how does virtual table/pointer code augments by the compiler?</strong> <p class="schema-faq-answer">- The code necessary to fill/override virtual table slot generated by the compiler at the time of compilation. To reiterate it in short, the <strong><em>virtual table is generated statically at the compile time</em></strong> by the compiler.<br/> in constructors right before user-written code.<br/>- Virtual table pointer(i.e. <code>_vptr</code>) has fixed offset. And the <strong><em>code to override </em></strong><code><em><strong>_vptr</strong></em></code><strong><em> is generated at the time of object construction</em></strong> by the compiler.<br/>- This is the reason that you should not call the virtual function in constructor. Read more about it <a rel="noreferrer noopener" href="https://stackoverflow.com/questions/962132/calling-virtual-functions-inside-constructors" target="_blank"><span style="color:#332ada" class="color">here</span></a>.</p> </div> <div class="schema-faq-section" id="faq-question-1587279471470"><strong class="schema-faq-question">Q. How do we know at runtime that pointer <code>protocol</code> will execute a right function(of the object pointed to)?</strong> <p class="schema-faq-answer">- In general, we don't know the exact type of the object <code>protocol</code> addresses at each invocation of <code>authenticate()</code>. However, we do know the virtual table pointer(<code>_vptr</code>) offset(which is fixed) associated with the object's class. <br/>- And using this <code>_vptr</code>, we can access the virtual table of the object pointed by <code>protocol</code> pointer. Again the index of function <code>authenticate()</code> in a virtual table fixed throughout the inheritance hierarchy. This way right <code>authenticate()</code> function execution guaranteed.</p> </div> </div>
<!-- /wp:yoast/faq-block -->

<!-- wp:heading -->
<h2>How `Pure` Virtual Function Works?</h2>
<!-- /wp:heading -->

<!-- wp:list -->
<ul><li>When you declare any function as pure virtual, the compiler automatically fills the slot of that pure virtual function with dummy function or so-called place holder <code>pure_virtual_called()</code> library instance. And the run-time exception placed if somehow this place holder called.  </li><li>In addition, rest of calling &amp; virtual table slot mechanism would be the same as a normal virtual function.</li></ul>
<!-- /wp:list -->

<!-- wp:heading -->
<h2>Virtual Function Support Under Multiple Inheritances</h2>
<!-- /wp:heading -->

<!-- wp:list -->
<ul><li>Now with multiple inheritance things will get a little bit tricky. To understand this behaviour let us take another simplified example as follow :</li></ul>
<!-- /wp:list -->

```c++
struct base1 {
    int base1_var;

    virtual void base1_func() { }            
    virtual void print() { }
};

struct base2 {
    int base2_var;
    
    virtual void base2_func() { }
    virtual void print() { }
};

struct derived : base1, base2 {
    int derived_var;

    void print() { }
};
```

<!-- wp:list -->
<ul><li>Here we have <code>derived</code> class with two base classes. In such a case, when we declare an object of the <code>derived</code> class, two virtual table pointers(<code>_vptr</code>) created in the <code>derived</code> class object. One for <code>base1</code> &amp; other for <code>base2</code>, which are overridden with the address of <code>derived</code> class virtual table. </li></ul>
<!-- /wp:list -->

<!-- wp:enlighter/codeblock -->
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">|                        |          
|------------------------| &lt;------ derived object memory layout
|  base1::base1_var      |          
|------------------------|          |--------->|----------------------|
|  base1::_vptr_base1    |----------|          |   type_info derived  |
|------------------------|                     |----------------------|
|  base2::base2_var      |                     |   base1::base1_func  |
|------------------------|                     |----------------------|
|  base2::_vptr_base2    |----------|          |    derived:::print   |
|------------------------|          |          |----------------------|
|  derived::derived_var  |          |          |------GUARD_AREA------|
|------------------------|          |--------->|----------------------|
|                        |                     |   type_info derived  |
|                        |                     |----------------------|
|                        |                     |   base2::base2_func  |
|                        |                     |----------------------|
                                               |    derived::print    |
                                               |----------------------|</pre>
<!-- /wp:enlighter/codeblock -->

<!-- wp:list -->
<ul><li>To understand that, first, let's assign a <code>base2</code> pointer with the address of a <code>derived</code> class object allocated on the heap:</li></ul>
<!-- /wp:list -->

```c++
base2 *pb = new derived;
```

<!-- wp:list -->
<ul><li>The address of the new <code>derived</code> object must be adjusted to address its <code>base2</code> <a rel="noreferrer noopener" href="http://www.vishalchovatiya.com/memory-layout-of-cpp-object/" target="_blank"><span style="color:#1f37d6" class="color">subobject</span></a>. The code augmentation done by compiler would look like:</li></ul>
<!-- /wp:list -->

```c++
base2* pb = static_cast<base2 *>(new derived()); 

// Equivalent to "address of derived object + sizeof(base1)"
```


<!-- wp:list -->
<ul><li>Visualizing memory object of above adjustment.</li></ul>
<!-- /wp:list -->

<!-- wp:enlighter/codeblock -->
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">        |                        |          
        |------------------------| &lt;------ derived object memory layout
        |  base1::base1_var      |          
        |------------------------|          |--------->|----------------------|
        |  base1::_vptr_base1    |----------|          |   type_info derived  |
pb ---> |------------------------|                     |----------------------|
        |  base2::base2_var      |                     |   base1::base1_func  |
        |------------------------|                     |----------------------|
        |  base2::_vptr_base2    |----------|          |    derived:::print   |
        |------------------------|          |          |----------------------|
        |  derived::derived_var  |          |          |------GUARD_AREA------|
        |------------------------|          |--------->|----------------------|
        |                        |                     |   type_info derived  |
        |                        |                     |----------------------|
        |                        |                     |   base2::base2_func  |
        |                        |                     |----------------------|
                                                       |    derived:::print   |
                                                       |----------------------|</pre>
<!-- /wp:enlighter/codeblock -->

<!-- wp:list -->
<ul><li>Without this adjustment, any nonpolymorphic use of the pointer would fail, such as</li></ul>
<!-- /wp:list -->

```c++
pb->base2_var = 5;
```

<!-- wp:list -->
<ul><li>And the call to the polymorphic function <code>print()</code> </li></ul>
<!-- /wp:list -->

```c++
pb->print();
```

<!-- wp:paragraph -->
<p>would probably transforms into</p>
<!-- /wp:paragraph -->

```c++
( * pb->_vptr_base2[ 2 ])( pb ); 
```

<!-- wp:heading -->
<h2>Summary</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>I hope you liked this material &amp; helps you to clarify many doubt around virtual function. There is one extraordinary case of <a rel="noreferrer noopener" href="http://www.vishalchovatiya.com/part-3-all-about-virtual-keyword-in-c-how-virtual-destructor-works/" target="_blank"><span style="color:#1310cb" class="color">virtual destructor</span></a> which we will see in-depth in PART-3 of this series. Followings are the points which sum up this article in concise way:</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><li>C++ standard does not define implementation &amp; it only states the behaviour of the dynamic dispatch(i.e. virtual function)</li><li>virtual table pointers(<code>_vptr</code>) is to object</li><li>virtual table pointer(<code>_vptr</code>) has fixed offset</li><li>code to override <code>_vptr</code> is generated at the time of object construction</li><li>virtual table is per class</li><li>virtual table is generated statically at the compile time<br></li></ol>
<!-- /wp:list -->


[Have Any Suggestions, Query or Wants to Say `Hi`? Take the Pressure Off, You Are Just a Click Away.](http://www.vishalchovatiya.com/contact-2/)🖱️