6

In the following code I don't understand why 'Derived1' requires the same amount of memory as 'Derived3'. Also is there any specific significance of size of Derived 4 being 16.

#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;
}

The output of this code gave was:

sizeof(Empty) 1
sizeof(Derived1) 1
sizeof(Derived2) 8
sizeof(Derived3) 1
sizeof(Derived4) 16
sizeof(Dummy) 1
  • 5
    Google "Empty base optimisation" – Angew is no longer proud of SO Jul 17 '18 at 12:06
  • 2
    An object cannot have a size of `0`, in other words it needs to have an address. Therefore even the "empty" classes need at least one byte. Therefore the classes that add a single `char` handle that requirement, so you don't need a "dummy" byte for the empty base class anymore after that. – Cory Kramer Jul 17 '18 at 12:10
  • 1
    Possible duplicate of [C++: What is the size of an object of an empty class?](https://stackoverflow.com/questions/621616/c-what-is-the-size-of-an-object-of-an-empty-class) –  Jul 17 '18 at 12:24
  • @NickyC The question you mentioned didn't really cover my doubt entirely. Thanks for the suggestion anyway – Tejas Sardana Jul 17 '18 at 15:51

2 Answers2

8

A class must have a sizeof of 1 or greater otherwise pointer arithmetic would break horribly, and the elements of array of that class would all occupy the same memory.

So sizeof(Derived1) is at least 1, as is sizeof(Empty). Empty base optimisation means that the size of the derived class is effectively zero.

sizeof(Derived3) can also be 1, since the single member is a char. Note that the compiler is again exploiting empty base optimisation here.

The polymorphic classes (i.e. those containing virtual keywords), have larger sizes due to your compiler implementing the requirements for polymorphic behaviour.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
2

In the following code I don't understand why 'Derived1' requires the same amount of memory as 'Derived3'.

Unlike all other objects, empty base-sub-objects are allowed to share their address with their sibling objects. Therefore an empty base does not need to occupy any memory whatsoever.

Besides the empty base, Derived3 contains nothing more than a char object. The size of char is 1, so Derived3 fits within the size of 1.

Besides the empty base, Derived1 contains nothing. But because all objects (excluding exceptions involving sub-objects) must have a unique address, the minimum size of any type is 1. Therefore the size of Derived1 is 1.

Also is there any specific significance of size of Derived 4 being 16.

No significance whatsoever. The size is quite typical.

eerorika
  • 232,697
  • 12
  • 197
  • 326