The following class contains some members of the same type:
template <typename T>
class MyClass
{
T m0;
T m1;
T m2;
T m3;
T m4;
//...
};
The members are all declared without an intervening access-specifier and thus are allocated that later members have higher addresses (ISO/IEC 14882: 9.2.12). The same paragraph says:
Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions (10.3) and virtual base classes (10.1).
Now let's assume that MyClass has no virtual functions and no virtual base classes. Is the following always true?
//inside a member function of MyClass
(char*)&m0 == (char*)&m0 + ((char*)&m1-(char*)&m0) * 0
(char*)&m1 == (char*)&m0 + ((char*)&m1-(char*)&m0) * 1
(char*)&m2 == (char*)&m0 + ((char*)&m1-(char*)&m0) * 2
(char*)&m3 == (char*)&m0 + ((char*)&m1-(char*)&m0) * 3
(char*)&m4 == (char*)&m0 + ((char*)&m1-(char*)&m0) * 4
Or is the compiler allowed to use arbitrary more padding than required (for whatever reasons...) ? For example: If sizeof(T)==4 and alignof(T)==8 the compiler will use 4 padding-bytes between the members. Would it be valid to use 12 padding-bytes only between m2 and m3?
What is the case when MyClass has virtual functions or virtual base classes? Is the compiler really allowed to insert information related to MyClass (like a vtable-ptr) between arbitrary data members? Or is the sentence from the standard above more related to virtual functions and virtual base classes of T? Because if it's valid to store information related to T outside T it could also have the following meaning:
template <typename T>
class MyClass
{
T m0;
//space to manage virtual functions and base classes of m0
//padding
T m1;
//space to manage virtual functions and base classes of m1
//padding
T m2;
//space to manage virtual functions and base classes of m2
//...
};
What again might give a regular pattern.