Today I Learned: Struct Packing With A Microsoft Twist

Member declaration order for structs and classes are important. You want to order the smallest to the largest (or vice versa) in order to avoid what’s known as ‘padding’. Padding is basically what the compiler will use to keep the memory allocation of the struct/class aligned in memory. This padding tends to be wasted space unless some compiler specific enhancement is occurring.

What I learned today was that Microsoft’s C++ compiler actually has extra padding involved, by design. And the solution to avoid the extra previous memory being stolen from you? Quite elementary, how could you not know? Inheriting from an empty abstract class makes your objects smaller.

I learned this today at work after mulling through some interesting articles another coworker provided. This one from a Remember Me programmer stood out immediately.

So say you have a struct with:

That is smaller in memory than:

There is 4 bytes in padding as opposed to 2 in the first example because you’ll have 2 bytes of padding before the Int32 and after the Int32 because it sits between the Int16s! This is actually somewhat basic and I’ve seen it before.

But when you have a virtual function in your class, what ends up happening is that the Microsoft compiler will throw in extra padding because the compiler takes virtual function and adds a ‘vtable’ pointer after it aligns the class data. Short and sweet: the compiler is stealing extra memory on Xbox 360 & Windows.

Again, this article explains everything I just went over really well and in a very humorous manner to boot. I wont try to re-explain more of what is an already very great read. It even gets a response in the comments from a gentleman who worked on the compiler 22~ years ago presumably at Microsoft.

Super interesting stuff. It’s an art in itself to notice these things and work around them. In games, these extra 4 bytes here and 8 bytes there multiple by 100-1000+ entities REALLY adds up quick and they need to be taken care of. The work arounds are never obvious, as we see here with inheriting from an empty abstract class resulting in less memory being used. It’s pretty crazy.

Worse yet, apparently, in Visual Studio 2013 – the extra padding issue is  even seen taking more memory than previously. The workaround still works, but its just really weird to see it evolve from VS2012!

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.