#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
директиви, вони визначені для реалізації.