Size of empty classes

Little trivia about empty classes…. Here’s the setup:

Question: what’s the size of Test0? What’s the size of Test1?

It’s a relatively well known fact that embedded empty classes are not actually free, and add 1 byte to the class containing them. So, knowing this, it shouldn’t be a surprise that sizeof(Test0)==2.

A more surprising fact, maybe, is that sizeof(Test1)==1. Yep, not free either, and a different size from Test0. It has to do with an obscure rule saying that the addresses of base classes must be different, or something. Can’t remember. Still, you need to keep this in mind if you don’t want to discover weird “ghost bytes” in your binary-serialized data.

Oh well.

7 Responses to “Size of empty classes”



  1. guardian Says:

    see there for more insight of vc++’s behavior: http://connect.microsoft.com/VisualStudio/feedback/details/100686/empty-member-optimization-not-working-properly

  2. Bruno Says:

    Just my 2 cents: this is called empty base class optimization :).

  3. David Black Says:

    Since when is writing a structure directly to a file a good idea anyway?

    At the very least you need to swizzle all fields to account for endian-ness.

    At which point you might as well write code to read/write each field individually (or have your reflection system do this). Then you know exactly what is being written irrespective of class/struct size.

  4. admin Says:

    Dave: it doesn’t matter if you *write* it directly or indirectly. What matters is how fast you can *load* it. And to make loading as fast as possible, you do want to write a copy of what you have in memory directly to disk. The loading then just becomes: fread one big block, call “finishing ctors” for objects in the block to initialize the v-tables, done. No data copy, no memory allocation, nada. Some people call this “load-in-place”. Reading each field individually is too slow for us.

    Anyway the problem with this is that everything gets written to disk: v-tables, padding bytes, mysterious bytes from the (lack of) empty base class optimization, etc. So yeah, everything counts. The great thing is that it makes you painfully aware of how much bytes you waste, and where. Especially when you then write converters from PC binary files to, say, PS3 binary files - the class layout is not always the same, so, serious “fun” follows.

  5. David Black Says:

    I am not convinced that such methods are a productive use of time. Except in special situations such as large arrays of vertices/pixels etc.

    However I guess if the serialization(if you can call it that) is for something faster than a disk(eg CPU=>Vector Processor) then it is probably a useful thing to blit more complex types(although still only simple POD types).

    [OT] Just got Wanted: Weapons of Fate(discounted price:-), the control system seems OK, I kinda like semi third person controls. But the menu system really sucks!(no vsync control, arghhh…) It also seems to work on W7 x64.. Wow:-P

  6. admin Says:

    “I am not convinced that such methods are a productive use of time”: why not? AFAIK Havok has been doing this for a long time. Many people use similar systems (see the recent posts on Maciej Sinilo’s blog for example). At least one big customer told us it was a *required* feature for them, otherwise they wouldn’t even look at the product. And my benchmarks tell me that the new loading code is an order of magnitude faster than before. I’d say it was well worth it overall… :)

  7. David Black Says:

    >>>”: why not?<<<

    It just sounds like it would be trouble to maintain. But if you are indeed seeing an order of magnitiude improvement then it may make sense. But i would be interested to know why it is so much faster… This might lead to additional insights.

shopfr.org cialis