#pragma pack
указывает компилятору упаковать элементы структуры с определенным выравниванием.Большинство компиляторов, когда вы объявляете структуру, вставляют заполнение между членами, чтобы гарантировать, что они выровнены по соответствующим адресам в памяти (обычно кратным размеру типа).Это позволяет избежать снижения производительности (или явной ошибки) на некоторых архитектурах, связанных с доступом к переменным, которые не выровнены должным образом.Например, с 4-байтовыми целыми числами и следующей структурой:
struct Test
{
char AA;
int BB;
char CC;
};
Компилятор может выбрать размещение структуры в памяти следующим образом:
| 1 | 2 | 3 | 4 |
| AA(1) | pad.................. |
| BB(1) | BB(2) | BB(3) | BB(4) |
| CC(1) | pad.................. |
и sizeof(Test)
будетбыть 4 × 3 = 12, даже если он содержит только 6 байтов данных.Наиболее распространенный вариант использования #pragma
(насколько мне известно) - это работа с аппаратными устройствами, когда вам нужно убедиться, что компилятор не вставляет отступы в данные и каждый элемент следует за предыдущим.При #pragma pack(1)
приведенная выше структура будет выглядеть так:
| 1 |
| AA(1) |
| BB(1) |
| BB(2) |
| BB(3) |
| BB(4) |
| CC(1) |
И sizeof(Test)
будет 1 × 6 = 6.
При #pragma pack(2)
, структура вышебудет выглядеть так:
| 1 | 2 |
| AA(1) | pad.. |
| BB(1) | BB(2) |
| BB(3) | BB(4) |
| CC(1) | pad.. |
И sizeof(Test)
будет 2 × 4 = 8.
Порядок переменных в структуре также важен.С переменными, упорядоченными следующим образом:
struct Test
{
char AA;
char CC;
int BB;
};
и с #pragma pack(2)
, структура будет выглядеть следующим образом:
| 1 | 2 |
| AA(1) | CC(1) |
| BB(1) | BB(2) |
| BB(3) | BB(4) |
и sizeOf(Test)
будет 3 × 2 = 6.