Упорядочение наследуемых типов в памяти - PullRequest
0 голосов
/ 22 марта 2020

Могу ли я предположить, что ячейки памяти членов класса расположены в том порядке, в котором они появляются в его определении, несмотря ни на что?

struct Color {
    uint8 r, g, b;
};
struct Vec3 {
    float x, y, z;
};

struct Object : public Color, Vec3 {
    uint32 data;
}object;

Другими словами, object.r всегда будет раньше object.x, что само по себе всегда будет до object.data?

Или, если быть более точным c, будет ли следующий код всегда верным?

assert( offsetof(Object, b)    ==  offsetof(Color, b) );
assert( offsetof(Object, z)    ==  sizeof(Color) + offsetof(Vec3, z) );
assert( offsetof(Object, data) ==  sizeof(Color) + sizeof(Vec3) );

1 Ответ

2 голосов
/ 22 марта 2020

Ваш класс Object не является стандартным макетом, потому что его (прямые и косвенные) не статичные c члены данных не все объявлены в одном классе.

Поэтому, в значительной степени, единственная гарантия у вас есть то, что члены, объявленные в одном и том же классе и с одним и тем же спецификатором доступа, упорядочены в соответствии с порядком их объявления:

r < g < b
x < y < z

и что порядок подобъектов подобъектов является согласованным, то есть если data < r также data < b и т. Д.

(имена должны представлять адреса здесь.)

Я не думаю, что есть какие-либо другие гарантии по стандарту C ++, но ABI, используемый вашей платформой, укажет это более подробно.

Кстати, поскольку класс не является стандартным макетом, offsetof имеет неопределенное поведение в C ++ 14 (и только условно - поддерживается с C ++ 17).

Утверждения не должны выполняться, даже если требования к упорядочению были выполнены, поскольку между подобъектами может быть заполнение.

...