C++: What is the size of an object of an empty class?

I was wondering what could be the size of an object of an empty class. It surely could not be 0 bytes since it should be possible to reference and point to it like any other object. But, how big is such an object?

I used this small program:

#include <iostream>
using namespace std;

class Empty {};

int main()
{
    Empty e;
    cerr << sizeof(e) << endl;
    return 0;
}

The output I got on both Visual C++ and Cygwin-g++ compilers was 1 byte! This was a little surprising to me since I was expecting it to be of the size of the machine word (32 bits or 4 bytes).

Can anyone explain why the size of 1 byte? Why not 4 bytes? Is this dependent on compiler or the machine too? Also, can someone give a more cogent reason for why an empty class object will not be of size 0 bytes?


Quoting Bjarne Stroustrup's C++ Style and Technique FAQ, the reason the size is non-zero is "To ensure that the addresses of two different objects will be different." And the size can be 1 because alignment doesn't matter here, as there is nothing to actually look at.


The standard states that all most derived objects have sizeof() >= 1:

Unless it is a bit-field (class.bit), a most derived object shall have a non-zero size and shall occupy one or more bytes of storage. Base class sub-objects may have zero size. ISO/IEC FDIS 14882:1998(E) intro.object


That's really an implementation detail. Once long ago, I thought it could be zero bytes or a thousand bytes, that it has no bearing on the language specification. But, after looking at the C++17 standard (expr.sizeof), sizeof is defined as always returning one or greater, no matter what.

The size of a most derived class shall be greater than zero.

This is required for, among other things, allowing you to handle arrays of objects and pointers to them. If your elements were allowed to be zero-sized then &(array[0]) would be identical to &(array[42]), which is going to cause all sorts of havoc to your processing loops.

The reason why it may not be a machine word is that there are no elements within it that actually require it to be aligned on a word boundary (such as an integer). For example, if you place char x; int y; inside the class, my GCC clocks it at eight bytes (since the second int must be aligned in that implementation).


Having said that, that particular wording appears to have been removed from C++20, allowing for at least the possibility of objects that can take up no space. However, the following text has been added to that same section:

When applied to a class, the result is the number of bytes in an object of that class including any padding required for placing objects of that type in an array.

Since arrays need to be able to distinguish between elements, that would mean sizeof would have to return at least one, even if the object itself technically took up no space.

So, different wording, but the same overall effect.