#pragma pack
instrui o compilador a compactar membros da estrutura com um alinhamento específico. A maioria dos compiladores, quando você declara uma estrutura, inserirá preenchimento entre os membros para garantir que eles estejam alinhados aos endereços apropriados na memória (geralmente um múltiplo do tamanho do tipo). Isso evita a penalidade de desempenho (ou erro definitivo) em algumas arquiteturas associadas ao acesso a variáveis que não estão alinhadas corretamente. Por exemplo, dados inteiros de 4 bytes e a seguinte estrutura:
struct Test
{
char AA;
int BB;
char CC;
};
O compilador pode escolher colocar a estrutura na memória da seguinte maneira:
| 1 | 2 | 3 | 4 |
| AA(1) | pad.................. |
| BB(1) | BB(2) | BB(3) | BB(4) |
| CC(1) | pad.................. |
e sizeof(Test)
seria 4 × 3 = 12, mesmo que contenha apenas 6 bytes de dados. O caso de uso mais comum para #pragma
(que eu saiba) é ao trabalhar com dispositivos de hardware nos quais você precisa garantir que o compilador não insira preenchimento nos dados e que cada membro siga o anterior. Com #pragma pack(1)
, a estrutura acima ficaria assim:
| 1 |
| AA(1) |
| BB(1) |
| BB(2) |
| BB(3) |
| BB(4) |
| CC(1) |
E sizeof(Test)
seria 1 × 6 = 6.
Com #pragma pack(2)
, a estrutura acima ficaria assim:
| 1 | 2 |
| AA(1) | pad.. |
| BB(1) | BB(2) |
| BB(3) | BB(4) |
| CC(1) | pad.. |
E sizeof(Test)
seria 2 × 4 = 8.
A ordem das variáveis em struct também é importante. Com variáveis ordenadas da seguinte forma:
struct Test
{
char AA;
char CC;
int BB;
};
e com #pragma pack(2)
, a estrutura seria apresentada assim:
| 1 | 2 |
| AA(1) | CC(1) |
| BB(1) | BB(2) |
| BB(3) | BB(4) |
e sizeOf(Test)
seria 3 × 2 = 6.
#pragma
diretivas, elas são definidas pela implementação.