I'm trying to understand struct and class padding in depth, so I devised an example I considered more challenging than many of the examples I found in tutorials on the topic. I compiled it in an x64 machine with g++, without enabling any code optimization. My code is as follows:
class Example
{
private:
long double foobar; // 10 bytes + 6 padded bytes as double follows
double barfoo; // 8 bytes + 8 padded bytes
static float barbar; // didn't count as it's a static member
float *fooputs; // 8 bytes + 8 padded bytes
int footsa; // 4 bytes, stored in the padded portion of float
char foo; // 1 byte, stored in the padded portion of float
public:
int function1(int foo) { return 1; }
void function2(int bar) { foobar = bar; }
};
int main()
{
std::cout << sizeof(Example) << std::endl; // 48 bytes
return 0;
}
Although I see that the size of Example
is 48 bytes, I expected it to be 37 bytes. The argumentation on my expectation is as follows:
foobar
needs 10 bytes. Asdouble
follows, 6 more bytes are needed for padding.barfoo
needs 8 bytes, as it's adouble
. No need for padding, asmod(16,8) == 0
*fooputs
needs 8 bytes, as it's a pointer in an x64 architecture. No need for padding, asmod(24,8) == 0
footsa
needs 4 bytes as an int. No need for padding, asmod(32,4) == 0
foo
needs 1 byte as a char. No need for padding.
As the result is different that the expected, I tried to understand how C++ evaluated the size of Example
to 48 bytes by commenting in and out class members. So, besides of the argumentation for foobar
I assumed the justifications I'm writing in my inline comments for each member.
Could anyone explain me how the size is evaluated to 48 bytes and if my justifications are correct?