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?
Приветствуются любые разъяснения!