All of the below will be done on GCC 9.1 using Compiler Explorer, in x86-64, using -O3.
I have this code:
struct Base {
    Base() {}
    double foo;
    int bar;
};
struct Derived : public Base {
    int baz;
};
int main(int argc, char** argv)
{
    return sizeof(Derived);
}
It correctly returns 16, as I would expect, 8 bytes for foo, and 4 bytes for bar and 4 bytes for baz. This works only because Derived inherits from Base and so it does not have to pad after bar due to Derived being a single type containing both Base and Derived elements.
I have two questions, as below:
First question
If I remove the explicit constructor of Base() {}, it starts returning 24, instead of 16. i.e. it adds padding after bar and baz.
I can't explain why having an explicit default constructor is any different to having an implicit default constructor.
Second question
If I then change struct to class for Base, it changes back to returning 16. I can not explain this either. Why would the access modifiers change the size of the structure?
 
     
     
    