Partilhar via


pack pragma

Especifica o alinhamento de empacotamento para membros da estrutura, união e classe.

Sintaxe

#pragma pack( show )
#pragma pack( push [ ,identifier ] [ ,n ] )
#pragma pack( pop [ , { identifier | n } ] )
#pragma pack( [ n ] )

Parâmetros

show
(Opcional) Exibe o valor de byte atual para alinhamento de embalagem. O valor é exibido por uma mensagem de aviso.

push
(Opcional) Empurra o valor de alinhamento de empacotamento atual na pilha interna do compilador e define o valor de alinhamento de empacotamento atual como n. Se n não for especificado, o valor atual do alinhamento da embalagem será enviado.

pop
(Opcional) Remove o registro da parte superior da pilha interna do compilador. Se n não for especificado com pop, o valor de embalagem associado ao registro resultante na parte superior da pilha será o novo valor de alinhamento de embalagem. Se n for especificado, por exemplo, #pragma pack(pop, 16), n se tornará o novo valor de alinhamento da embalagem. Se você aparecer usando um identifier, por exemplo, #pragma pack(pop, r1), todos os registros na pilha serão exibidos até que o registro que identifier seja encontrado. Esse registro é exibido e o valor de empacotamento associado ao registro encontrado na parte superior da pilha torna-se o novo valor de alinhamento de embalagem. Se você aparecer usando um identifier que não é encontrado em nenhum registro na pilha, o pop será ignorado.

A declaração #pragma pack (pop, r1, 2) é equivalente a #pragma pack (pop, r1) seguida de #pragma pack(2).

identifier
(Opcional) Quando usado com push, atribui um nome ao registro na pilha interna do compilador. Quando usado com pop, retira registros da pilha interna até que identifier seja removido. Se identifier não for encontrado na pilha interna, nada será exibido.

n
(Opcional) Especifica o valor, em bytes, a ser usado para empacotamento. Se a opção do compilador /Zp não estiver definida para o módulo, o valor padrão para n será 8. Os valores válidos são 1, 2, 4, 8 e 16. O alinhamento de um membro está em um limite que é um múltiplo de nou um múltiplo do tamanho do membro, o que for menor.

Comentários

Para pacote uma classe é colocar seus membros diretamente um após o outro na memória. Isso pode significar que alguns ou todos os membros podem ser alinhados em um limite menor do que o alinhamento padrão da arquitetura de destino. pack dá controle no nível da declaração de dados. Ele difere da opção do compilador /Zp, que fornece apenas controle no nível do módulo. embalagem entra em vigor no primeiro struct, unionou class declaração após a pragma ser vista. pack não tem qualquer efeito sobre as definições. Chamar pack sem argumentos define n para o valor definido na opção do compilador /Zp. Se a opção do compilador não estiver definida, o valor padrão será 8 para x86, ARM e ARM64. O padrão é 16 para x64 nativo e ARM64EC.

Se você alterar o alinhamento de uma estrutura, ela pode não usar tanto espaço na memória. No entanto, você pode ver uma perda de desempenho ou até mesmo obter uma exceção gerada por hardware para acesso não alinhado. Você pode modificar esse comportamento de exceção usando SetErrorMode.

Para obter mais informações sobre como modificar o alinhamento, consulte estes artigos:

  • alignof

  • align

  • __unaligned

  • exemplos de alinhamento de estrutura x64

    Advertência

    No Visual Studio 2015 e posterior, você pode usar os operadores alignas e alignof padrão, que, ao contrário __alignof e __declspec( align ), são portáteis entre compiladores. O padrão C++ não aborda o empacotamento, então você ainda deve usar pack (ou a extensão correspondente em outros compiladores) para especificar alinhamentos menores do que o tamanho da palavra da arquitetura de destino.

Exemplos

O exemplo a seguir mostra como usar o packpragma para alterar o alinhamento de uma estrutura.

// pragma_directives_pack.cpp
#include <stddef.h>
#include <stdio.h>

struct S {
   int i;   // size 4
   short j;   // size 2
   double k;   // size 8
};

#pragma pack(2)
struct T {
   int i;
   short j;
   double k;
};

int main() {
   printf("%zu ", offsetof(S, i));
   printf("%zu ", offsetof(S, j));
   printf("%zu\n", offsetof(S, k));

   printf("%zu ", offsetof(T, i));
   printf("%zu ", offsetof(T, j));
   printf("%zu\n", offsetof(T, k));
}
0 4 8
0 4 6

O exemplo a seguir mostra como usar o push, pope mostrar sintaxe.

// pragma_directives_pack_2.cpp
// compile with: /W1 /c
#pragma pack()   // n defaults to 8; equivalent to /Zp8
#pragma pack(show)   // C4810
#pragma pack(4)   // n = 4
#pragma pack(show)   // C4810
#pragma pack(push, r1, 16)   // n = 16, pushed to stack
#pragma pack(show)   // C4810

// pop to the identifier and then set
// the value of the current packing alignment:
#pragma pack(pop, r1, 2)   // n = 2 , stack popped
#pragma pack(show)   // C4810

Ver também

diretivas Pragma e as palavras-chave __pragma e _Pragma