Will sizeof always be the same?
sizeof is compile time constant. So for any program that has been compiled, the sizeof will not change between executions. There is no such guarantee for different compilations of the program however. In fact, when program is compiled for another system, it is quite typical for sizeof and alignof of even fundamental types to be different.
I know I can reorder ... can a compiler make this decision?
There are restrictions for standard layout classes. The first member is guaranteed to have the same address as the super object. Also, for any such classes with same types of members in same order at the beginning of declaration order, that "common initial sequence" may be accessed through separate members of union, which in practice mean that they must have the same address, which effectively prevents any re-ordering of members because compiler cannot know what other classes with potentially shared common initial sequences there may be. A
is a standard layout class.
These restrictions don't apply to non-standard layout classes, with which the compiler is allowed to be more relaxed. As far as I know, the language doesn't prevent the compiler from choosing the order of members of non-standard layout classes. But in practice, in order to link together object files that have been compiled separately, those object files must conform to the same binary interface, i.e. they need to have the same representation for types. If the compiler used one layout for one compilation, and different layout for another, that would break the ABI. So, whatever order the compiler chooses, it should stick to it. And any compiler that intends to be compatible, should use that same ABI. For what it's worth the Itanium ABI, used by GCC, specifies:
2.4 Non-POD Class Types
II. Allocation of Members Other Than Virtual Bases
For each data component D (first the primary base of C, if any, then the non-primary, non-virtual direct base classes in declaration order, then the non-static data members and unnamed bit-fields in declaration order) ...
Or is it the always the programmer's responsibility? (I'm assuming the compiler can't reorder)
It's best for the programmer to assume that sub objects are in declaration order, and to choose that order in a way to minimise padding. It's best to not assume the order of sub objects for purposes of accessing memory of non-standard layout classes.