Running this code below, the sizeof base class and derived class are both 32.
#include "iostream"
#include "string"
using namespace std;
class base{
//public:
int a;
double b;
void * c;
char d;
};
class c1 : base{
//public:
int a;
};
int main() {
cout << sizeof(base) << endl;
cout << sizeof(c1) << endl;
return 0;
}
However, if you undo the comment of keyword public:
, sizeof derived class becomes 40.
I am totally lost here, why member variable being private or not affect the overall size?
Reproducible in GCC.
Running this code below, the sizeof base class and derived class are both 32.
#include "iostream"
#include "string"
using namespace std;
class base{
//public:
int a;
double b;
void * c;
char d;
};
class c1 : base{
//public:
int a;
};
int main() {
cout << sizeof(base) << endl;
cout << sizeof(c1) << endl;
return 0;
}
However, if you undo the comment of keyword public:
, sizeof derived class becomes 40.
I am totally lost here, why member variable being private or not affect the overall size?
Reproducible in GCC.
If you were using Clang, you may add -Xclang -fdump-record-layouts
to get a look at actual layout compiler makes for you.
If you make member variables in base class public, you get the layout shown as below:
*** Dumping AST Record Layout
0 | class base
0 | int a
8 | double b
16 | void * c
24 | char d
| [sizeof=32, dsize=32, align=8,
| nvsize=32, nvalign=8]
As you can see the dsize and nvsize both have already taken 32 bytes. There is no room for merge of int a
from derived class, namely c1 in your code.
The justification of compiler comes down to this ABI specification:
If C is a POD, but not a POD for the purpose of layout, set dsize(C) = nvsize(C) = sizeof(C).
A funny enough fact is, by adding a dummy constructor in your base class, sizeof(base) will be 32, because you effectively made your base a non-POD one, compiler is free to apply all sort of optimizations now.
std::endl
does. Use'\n'
to end a line unless you have a good reason not to. – Pete Becker Commented Jan 8 at 13:18