#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.
#pragma
директивы, они определены реализацией.