pack pragma

Spécifie l’alignement d’emballage pour les membres de structure, d’union et de classe.

Syntaxe

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

Paramètres

show
(Facultatif) Affiche la valeur d’octet actuelle pour l’alignement de l’emballage. La valeur est affichée par un message d'avertissement.

push
(Facultatif) Envoie (push) la valeur d’alignement de l’emballage actuelle sur la pile du compilateur interne et définit la valeur d’alignement de l’emballage actuelle sur n. Si n’est pas spécifié, la valeur d’alignement de l’emballage actuelle est envoyée (push).

pop
(Facultatif) Supprime l’enregistrement du haut de la pile du compilateur interne. Si n’est pas spécifié avec pop, la valeur d’emballage associée à l’enregistrement résultant en haut de la pile est la nouvelle valeur d’alignement d’emballage. Si n est spécifié, par exemple, #pragma pack(pop, 16)n devient la nouvelle valeur d’alignement d’emballage. Si vous utilisez un identifierenregistrement , par exemple, #pragma pack(pop, r1)tous les enregistrements de la pile sont dépilés jusqu’à ce que l’enregistrement trouvé identifier soit trouvé. Cet enregistrement est dépilé et la valeur d’emballage associée à l’enregistrement trouvé en haut de la pile devient la nouvelle valeur d’alignement de l’emballage. Si vous utilisez un identifier enregistrement introuvable dans la pile, celui-ci pop est ignoré.

L’instruction #pragma pack (pop, r1, 2) est équivalente à #pragma pack (pop, r1) la suivante #pragma pack(2).

identifier
(Facultatif) Lorsqu’il est utilisé avec push, attribue un nom à l’enregistrement sur la pile du compilateur interne. Lorsqu’il est utilisé avec pop, affiche les enregistrements hors de la pile interne jusqu’à ce qu’il identifier soit supprimé. S’il identifier n’est pas trouvé sur la pile interne, rien n’est dépilé.

n
(Facultatif) Spécifie la valeur, en octets, à utiliser pour l’emballage. Si l’option /Zp du compilateur n’est pas définie pour le module, la valeur par défaut est n 8. Les valeurs valides sont 1, 2, 4, 8 et 16. L’alignement d’un membre se trouve sur une limite qui est soit un multiple de n, soit un multiple de la taille du membre, selon ce qui est plus petit.

Notes

Pour empaqueter une classe, il faut placer ses membres directement après l’autre en mémoire. Cela peut signifier que certains membres ou tous les membres peuvent être alignés sur une limite inférieure à l’alignement par défaut de l’architecture cible. pack donne le contrôle au niveau de la déclaration de données. Il diffère de l’option /Zpdu compilateur, qui fournit uniquement un contrôle au niveau du module. le pack prend effet au premier struct, unionou class déclaration après la pragma vue. pack n’a aucun effet sur les définitions. Appel pack sans argument défini sur la valeur définie n dans l’option /Zpdu compilateur . Si l’option du compilateur n’est pas définie, la valeur par défaut est 8 pour x86, ARM et ARM64. La valeur par défaut est 16 pour les ARM64EC natifs x64.

Si vous modifiez l’alignement d’une structure, il peut ne pas utiliser autant d’espace en mémoire. Toutefois, vous pouvez constater une perte de performances ou même obtenir une exception générée par le matériel pour un accès non aligné. Vous pouvez modifier ce comportement d’exception à l’aide SetErrorModede .

Pour plus d’informations sur la modification de l’alignement, consultez les articles suivants :

  • alignof

  • align

  • __unaligned

  • Exemples d’alignement de structure x64

    Avertissement

    Dans Visual Studio 2015 et versions ultérieures, vous pouvez utiliser les opérateurs standard alignas et alignof les opérateurs, contrairement __alignof__declspec( align ) aux compilateurs. La norme C++ ne traite pas de l’empaquetage. Vous devez donc toujours utiliser pack (ou l’extension correspondante sur d’autres compilateurs) pour spécifier des alignements plus petits que la taille du mot de l’architecture cible.

Exemples

L’exemple suivant montre comment utiliser l’alignement packpragma d’une structure.

// 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

L’exemple suivant montre comment utiliser la syntaxe Push, Pop et Show .

// 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

Voir aussi

Directives pragma et les __pragma_Pragma mot clé