Выравнивание структуры в Visual C++

Visual C++ предлагает как переключатель компилятора (/Zp), так и прагму pack, чтобы повлиять на выравнивание элементов структуры. Тем не менее, у меня, кажется, есть некоторое неправильное представление о том, как они работают.

Согласно MSDN , для заданного значения выравнивания n

выравнивание члена будет на границе, которая является кратно n или кратно размеру элемента, в зависимости от того, что меньше.

Предположим, что значение пакета равно 8 байтам (, что является значением по умолчанию). Я думаю, что внутри структуры любой элемент, размер которого меньше 8 байт, будет иметь смещение, кратное его собственному размеру. Любой член, размер которого составляет 8 байтов или более, будет иметь смещение, кратное 8 байтам.

Теперь возьмите следующую программу.:

#include 

#pragma pack(8)

struct Foo {
    int i1;
    int i2;
    char c;
};

struct Bar {
    char c;
    Foo foo;
};

int _tmain(int argc, _TCHAR* argv[]) {
    int fooSize = sizeof(Foo); // yields 12
    Bar bar;
    int fooOffset = ((int) &bar.foo) - ((int) &bar); // yields 4

    return 0;
}

Структура Fooимеет размер 12 байт. Таким образом, внутри Barя ожидаю, что член Fooбудет иметь смещение 8 (кратное 8), хотя на самом деле это смещение 4. Почему это так?

Кроме того, Fooдействительно имеет только 4+4+1 = 9 байт данных. Компилятор автоматически добавляет байты заполнения в конце. Но опять же, учитывая значение выравнивания 8 байтов, не должно ли оно быть кратным 8, а не 4?

Приветствуются любые разъяснения!

6
задан Daniel Wolf 21 April 2012 в 10:08
поделиться