I now GROK empty class (and empty base optimizations) fully on MSVC and GCC.
----------------------------------------------------------
GCC C++ follows these rules:
- class EmptyBase {}; --> sizeof(EmptyBase) == 1
- Any number of empty-bases will map to 0 in the struct offset as long as all are unique types (including parenting).
- Non empty-base parents are simply in the order declared with only padding for alignment.
- If the first member of a derived class that immediately follows empty-bases does not derive from any of those bases, it is allowed to start at the first properly aligned offset for that member that is greater-than-or-equal-to the empty-base address -- this may be the same address as the empty-bases.
- If the first member of a derived class that immediately follows empty-bases does derive from any of those bases, it will start at the first properly aligned offset for that member that is greater-than the empty-base address -- this is never the same address as the empty-bases.
- Members that are empty-classes take at least one byte of storage in the containing class.
----------------------------------------------------------
MSVC++ follows these rules:
- class EmptyBase {}; --> sizeof(EmptyBase) == 1
- The only way an empty-base class (or class derived from an empty-base) will start at offset 0 (zero) is if it is the first base class.
- A Non-empty-base class will start at the next valid alignment offset for the base class.
- All empty-base classes will appear to have zero effective storage in the derived class and do not affect the current offset unless followed by another empty-base class (or class derived from an empty-base) in which case you should see the following rule.
- An empty-base class (or class derived from an empty-base) that follows an empty-base class (or class derived from an empty-base) will add 1 to the current offset position before padding to the proper alignment for the class.
- There is no padding (other than for alignment) between the last base class and the first class member or vft-pointer(s). *** NOTE: this is an over-aggressive empty-base-optimization that can break the C++ standard.
- Members that are empty-classes take at least one byte of storage in the containing class.