7

With the code:

#include <iostream>

class A {};
class B { char x; };

int main()
{
    std::cerr << sizeof(A) << " " << sizeof(B) << std::endl;
}

I know that it's a common interview question to ask the size of an empty class - and I know the answer is one.

My question is... what is held in that "1" byte for an empty class (I'm guessing its empty), and what does the compiler do internally to make it so that sizeof B is the same as sizeof A in this case?

I'd like to fully understand it rather than just know the answer.

John Humphreys
  • 37,047
  • 37
  • 155
  • 255
  • That depends on the implementation of the compiler. There is also the question : Why do you care? – BЈовић Aug 01 '11 at 14:30
  • 8
    Who asks that in an interview? That is a terrible interview question. – nmichaels Aug 01 '11 at 14:31
  • 2
    Take a look here : http://stackoverflow.com/questions/621616/c-what-is-the-size-of-an-object-of-an-empty-class – a1ex07 Aug 01 '11 at 14:32
  • 1
    Duplicate : http://stackoverflow.com/questions/621616/c-what-is-the-size-of-an-object-of-an-empty-class – Matthieu Aug 01 '11 at 14:34
  • 1
    If you make B derive from A it's still one byte. Just a small tidbit. – dascandy Aug 01 '11 at 14:38
  • @ VJo: I couldn't care less, but alot of people ask things like this in interviews for some reason or another. Last time I was job hunting I got hit by it in 2 different places, so its better to know than not know. – John Humphreys Aug 01 '11 at 14:38
  • @ a1ex07 and Matthieu, thanks - the other one has a stroustrup reference that's useful :) sorry I missed that! – John Humphreys Aug 01 '11 at 14:40

3 Answers3

8

This isn’t really a meaningful question: The runtime just marks the one byte as occupied so that no other object will be allocated at its position. But there isn’t anything “held” there to occupy the byte.

The only reason for this rule is that objects must be uniquely identifiable. An object is identified by the address it has in memory. To ensure that no two objects have the same address (except in the case of base class objects), objects of empty classes “occupy” memory by having a non-zero size.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • Nevertheless IMHO - it's a very weak argument. So what if two *empty* objects do share their starting address? I believe that was ok in the times of K&R C, when there was no point in creating *empty* objects anyway. OTOH with the arrival of C++ things have changed. You may want to have an empty object with non-trivial d'tor. Plus empty objects may arise in the template meta-programming – valdo Aug 02 '11 at 08:44
  • 4
    @valdo That’s a misconception. Unique identification of objects is *essential*. Objects in C++ are *defined* by the memory they occupy (object = memory location by definition). If objects would share an address the runtime would be unable to distinguish them. This would break all kinds of assumptions underlying the C++ type system. To give just one concrete example, it would break arrays and pointer arithmetic. – Konrad Rudolph Aug 02 '11 at 11:37
4

There is no requirement in the C++ standard that an empty object should have one byte of memory occupied. It is purely based on the implementation.

EDIT: true, it's conforming ( ISO/IEC 14882 p.149 ):

9 Classes [class]
..
..
..
3 Complete objects and member subobjects of class type shall have nonzero size ...

cprogrammer
  • 5,503
  • 3
  • 36
  • 56
-1

You can often see a similar effect in classes like these :

class Foo {
  int a;
  char b;
}; // sizeof(Foo) > sizeof(int) + sizeof(char)

Not all memory in a C++ object needs to have a name. Unnames memory inside an object is commnoly called "padding". Your empty class happens to have one byte of padding. One of the most common reasons why C++ compilers insert padding is to allow use of a class in an array type.

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • That is correct, but in the case of empty classes, a different effect is at work, as explained by the other answers. Empty classes must have non-zero size because the C++ standard demands it, but padding is something that compilers choose to implement. – Stefan Majewsky Jul 24 '14 at 09:16