
Источник: http://geeksforgeeks.org/?p=9705
В сумме: оптимизирует упаковку битов (для этого предназначены битовые поля) как можно больше.без ущерба для выравнивания.
Выравнивание данных переменной связано с тем, как данные хранятся в этих банках.Например, естественное выравнивание int на 32-битной машине составляет 4 байта.Когда тип данных выровнен естественным образом, центральный процессор выбирает его в минимальных циклах чтения.
Аналогично, естественное выравнивание short int
составляет 2 байта.Это означает, что короткий int может храниться в паре банк 0 - банк 1 или пара банк 2 - банк 3.double
требует 8 байтов и занимает две строки в банках памяти.Любое смещение double приведет к тому, что более двух циклов чтения приведет к получению двойных данных.
Обратите внимание, что двойная переменная будет размещена на границе 8 байтов на 32-битной машине и требует двух циклов чтения из памяти.На 64-битной машине, основанной на количестве банков, двойная переменная будет размещена на границе 8 байт и требует только один цикл чтения из памяти.
Таким образом, компилятор введет требование выравнивания для каждой структуры.Это будет как у самого крупного члена структуры.Если вы удалите char
из вашего struct
, вы все равно получите 4 байта .
В вашем struct
, char
выровнено на 1 байт.За ним следует битовое поле int
, которое выровнено на 4 байта для целых чисел, но вы определили битовое поле.
8 бит = 1 байт.Char
может быть любой байтовой границей.Итак Char
+ Int:8
= 2 байта.Ну, это нечетная граница байтов, поэтому компилятор добавляет дополнительные 2 байта для поддержки 4-байтовой границы.
Чтобы она была 8 байтов, вам нужно было бы объявить фактическую int
(4 байта)и char
(1 байт).Это 5 байтов.Ну, это еще одна нечетная граница байтов, поэтому struct
дополняется до 8 байтов .
В прошлом я обычно делал, чтобы контролировать заполнение, чтобы поместить заполнители между моими struct
, чтобы всегда поддерживать 4-байтовую границу.Поэтому, если у меня есть struct
, как это:
struct s {
int id;
char b;
};
Я собираюсь вставить распределение следующим образом:
struct d {
int id;
char b;
char temp[3];
}
Это даст мне struct
с размером4 байта + 1 байт + 3 байта = 8 байт!Таким образом, я могу гарантировать, что мой struct
дополнен так, как я хочу, особенно если я передаю его куда-нибудь по сети.Кроме того, если я когда-нибудь изменю свою реализацию (например, если бы мне нужно было сохранить этот struct
в двоичный файл, заполнители были там с самого начала и до тех пор, пока я поддерживаю свою первоначальную структуру,все хорошо!)
Наконец, вы можете прочитать этот пост на C Размер структуры с битовыми полями для более подробного объяснения.