Всегда ли заполнение между членами класса одного и того же типа? - PullRequest
3 голосов
/ 29 июня 2010

Следующий класс содержит несколько членов одного типа:

template <typename T>
class MyClass
{
    T m0;
    T m1;
    T m2;
    T m3;
    T m4;
    //...
};

Все члены объявляются без промежуточного спецификатора доступа и, таким образом, распределяются так, чтобы более поздние члены имели более высокие адреса (ISO / IEC 14882: 9.2.12). В том же абзаце написано:

Требования к выравниванию реализации может вызвать двух соседних членов не распределяется сразу после каждого Другой; то же самое касается требований к пространству для управления виртуальными функциями (10.3) и виртуальными базовыми классами (10.1).

Теперь давайте предположим, что MyClass не имеет виртуальных функций и виртуальных базовых классов. Всегда ли верно следующее?

//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

Или компилятору разрешено использовать произвольно больше отступов, чем требуется (по каким-либо причинам ...)? Например: если sizeof (T) == 4 и alignof (T) == 8, компилятор будет использовать 4 байта заполнения между членами. Будет ли допустимо использовать 12 дополнительных байтов только между м2 и м3?

В каком случае MyClass имеет виртуальные функции или виртуальные базовые классы? Разрешено ли компилятору вставлять информацию, связанную с MyClass (например, vtable-ptr) между произвольными элементами данных? Или предложение из стандарта выше больше связано с виртуальными функциями и виртуальными базовыми классами T? Потому что, если допустимо хранить информацию, относящуюся к T, вне T, это также может иметь следующее значение:

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
    //...
};

Что опять-таки может дать регулярную картину.

1 Ответ

3 голосов
/ 29 июня 2010

Нет.Нет никаких правил, предписывающих это, поэтому компиляторы могут вставлять отступы где угодно.«Требования выравнивания могут ...» - это всего лишь пример, а не ограничение возможных причин.

Если бы у вас был член T m[5], то было бы иначе, в этом случае &(this->m[1]) - &(this->m[0]) == 1.

По той же причине: "Разрешено ли компилятору вставлять информацию, связанную с MyClass (например, vtable-ptr) между произвольными элементами данных?"нужно ответить положительно, потому что нет правила, которое запрещает это.Он не мог вставить его в середину подобъекта (будь то T или T[5]), но между подобъектами все в порядке.

...