6

Can anyone tell the exact reason for the output of the following code in C++ ?The output that I received for the code is included in header comments. What does it have to do with virtual table and v pointer.

/* sizeof(Empty) 1                                                                                
 sizeof(Derived1) 1 
 sizeof(Derived2) 8 
 sizeof(Derived3) 1 
 sizeof(Derived4) 16 
 sizeof(Dummy) 1
*/

#include <iostream>
using namespace std;

class Empty
{};

class Derived1 : public Empty
{};

class Derived2 : virtual public Empty
{};

class Derived3 : public Empty
{    
char c;
};

class Derived4 : virtual public Empty
{
char c;
};

class Dummy
{
 char c;
};

int main()
{

    cout << "sizeof(Empty) " << sizeof(Empty) << endl;
    cout << "sizeof(Derived1) " << sizeof(Derived1) << endl;
    cout << "sizeof(Derived2) " << sizeof(Derived2) << endl;
    cout << "sizeof(Derived3) " << sizeof(Derived3) << endl;
    cout << "sizeof(Derived4) " << sizeof(Derived4) << endl;    
    cout << "sizeof(Dummy) " << sizeof(Dummy) << endl;
    return 0;

}
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055

3 Answers3

4

Firstly, even a class with no members must have a non-zero size. The standard insists on that. Otherwise pointer arithmetic and arrays would not work as an array of a zero-sized class would have all its elements in the same place!

The fact that the other sizes differ may well be due to a v-table. But that is not mandated explicitly in the standard, so is a manifestation of the way your compiler is dealing with things.

Note also that polymorphism requires at least one virtual method to be defined in a base class. This accounts for sizeof(Derived1) being the same size as the base class.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • Could the v-table be omitted while retaining standard compliance in this case? In other words, could the compiler ignore the `virtual` inheritance, since there are no fields nor virtual methods in the base class? – chi Jun 25 '15 at 14:13
2

The difference in the size is because of vptr added by the compiler.

sizeof(Derived1) = 1, it is because as per C++ standards empty class always occupies 1 byte of memory.

sizeof(Derived2) = 8, Since it inherits virtual base class Derived1,So a vptr is added by the compiler (sizeof(vptr) = 8 on a 64 bit machine) and hence the sizeof(Derived2) is showing 8 bytes.

sizeof(Derived3) = 1 because of 1 byte of the char.

sizeof(Derived4) = 16, internal implementation of Virtual inheritance is completely dependent on the compiler, because of this you are seeing 16 bytes as the size.

sizeof(Dummy) = 1 Since it contains a single char entity.

Rndp13
  • 1,094
  • 1
  • 21
  • 35
2

Empty has size 1 because every object must have a size of at least 1.

Derived1 has size 1 for the same reason.

Derived2 has size 8 because your compiler needs 8 bytes for the virtual inheritance (probably a pointer).

Derived3 has size 1 because your compiler has applied the "empty base class" optimisation.

Derived4 has size 16 because the 8 bytes needed for the virtual inheritance make the object need 8-byte alignment.

Dummy has size 1 because that is the size of a char.

molbdnilo
  • 64,751
  • 3
  • 43
  • 82