Я не уверен, соответствует ли это фактическому стандарту C / C ++, и я склонен сказать, что это зависит от компилятора (просто чтобы быть в безопасности). Тем не менее, мне было очень весело выяснить это несколько месяцев назад, когда мне приходилось отправлять динамически сгенерированные структуры C в виде байтовых массивов по сети как часть протокола для связи с чипом. Выравнивание и размер всех структур должны были соответствовать структурам в коде, работающем на чипе, который был скомпилирован с вариантом GCC для архитектуры MIPS. Я попытаюсь дать алгоритм, и он должен применяться ко всем вариантам gcc (и, надеюсь, большинству других компиляторов).
Все базовые типы, такие как char , short и int , соответствуют их размеру, и они выравниваются на следующую доступную позицию, независимо от выравнивание родителя . И чтобы ответить на исходный вопрос, да, общий размер кратен выравниванию.
// size 8
struct {
char A; //byte 0
char B; //byte 1
int C; //byte 4
};
Несмотря на то, что выравнивание структуры составляет 4 байта, символы по-прежнему упакованы как можно ближе.
Выравнивание структуры равно наибольшему выравниванию его членов .
* * Пример тысяча двадцать-один: * * 1 022
//size 4, but alignment is 2!
struct foo {
char A; //byte 0
char B; //byte 1
short C; //byte 3
}
//size 6
struct bar {
char A; //byte 0
struct foo B; //byte 2
}
Это также относится к профсоюзам и любопытным образом. Размер объединения может быть больше любого из его размеров, просто из-за выравнивания:
//size 3, alignment 1
struct foo {
char A; //byte 0
char B; //byte 1
char C; //byte 2
};
//size 2, alignment 2
struct bar {
short A; //byte 0
};
//size 4! alignment 2
union foobar {
struct foo A;
struct bar B;
}
Используя эти простые правила, вы должны быть в состоянии выяснить выравнивание / размер любого ужасно вложенного объединения / структуры, с которыми вы столкнетесь. Это все из памяти, поэтому, если я пропустил угловой случай, который не может быть решен из этих правил, пожалуйста, дайте мне знать!