#pragma pack
indica al compilador que empaque los miembros de la estructura con una alineación particular. La mayoría de los compiladores, cuando declara una estructura, insertará relleno entre los miembros para asegurarse de que estén alineados con las direcciones apropiadas en la memoria (generalmente un múltiplo del tamaño del tipo). Esto evita la penalización de rendimiento (o error absoluto) en algunas arquitecturas asociadas con el acceso a variables que no están alineadas correctamente. Por ejemplo, dados enteros de 4 bytes y la siguiente estructura:
struct Test
{
char AA;
int BB;
char CC;
};
El compilador podría elegir colocar la estructura en la memoria de esta manera:
| 1 | 2 | 3 | 4 |
| AA(1) | pad.................. |
| BB(1) | BB(2) | BB(3) | BB(4) |
| CC(1) | pad.................. |
y sizeof(Test)
sería 4 × 3 = 12, aunque solo contenga 6 bytes de datos. El caso de uso más común para #pragma
(según mi conocimiento) es cuando se trabaja con dispositivos de hardware en los que debe asegurarse de que el compilador no inserte relleno en los datos y que cada miembro siga el anterior. Con #pragma pack(1)
, la estructura anterior se presentaría así:
| 1 |
| AA(1) |
| BB(1) |
| BB(2) |
| BB(3) |
| BB(4) |
| CC(1) |
Y sizeof(Test)
sería 1 × 6 = 6.
Con #pragma pack(2)
, la estructura anterior se presentaría así:
| 1 | 2 |
| AA(1) | pad.. |
| BB(1) | BB(2) |
| BB(3) | BB(4) |
| CC(1) | pad.. |
Y sizeof(Test)
sería 2 × 4 = 8.
El orden de las variables en struct también es importante. Con variables ordenadas de la siguiente manera:
struct Test
{
char AA;
char CC;
int BB;
};
y con #pragma pack(2)
, la estructura se presentaría así:
| 1 | 2 |
| AA(1) | CC(1) |
| BB(1) | BB(2) |
| BB(3) | BB(4) |
y sizeOf(Test)
sería 3 × 2 = 6.
#pragma
directivas, están definidas en la implementación.