Sdílet prostřednictvím


pack pragma

Určuje zarovnání balení pro členy struktury, sjednocení a třídy.

Syntaxe

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

Parametry

show
(Volitelné) Zobrazí aktuální hodnotu bajtu pro zarovnání balení. Tato hodnota se zobrazí zprávou s upozorněním.

push
(Volitelné) Nasdílí aktuální hodnotu zarovnání balení do zásobníku interního kompilátoru a nastaví aktuální hodnotu zarovnání balení na n. Pokud není zadána hodnota n , aktuální hodnota zarovnání balení se nasdílí.

pop
(Volitelné) Odebere záznam z horní části interního zásobníku kompilátoru. Pokud n není zadán pops , pak hodnota balení přidružená k výslednému záznamu v horní části zásobníku je nová hodnota zarovnání balení. Pokud je například zadán #pragma pack(pop, 16)n , n se stane novou hodnotou zarovnání balení. Pokud například spustíte okno s použitím záznamu identifier, zobrazí se všechny záznamy v zásobníku, #pragma pack(pop, r1)dokud se nenajde záznam.identifier Tento záznam se přepne a hodnota balení přidružená k záznamu nalezeného v horní části zásobníku se stane novou hodnotou zarovnání balení. Pokud se zobrazí okno identifier s použitím záznamu, který není v žádném záznamu v zásobníku, bude pop ignorován.

#pragma pack (pop, r1, 2) Příkaz je ekvivalentní #pragma pack (pop, r1) následovaný #pragma pack(2).

identifier
(Volitelné) Při použití se pushzáznamem v interním zásobníku kompilátoru přiřadí název záznamu. Při použití se popvyskočí záznamy z interního zásobníku, dokud identifier se neodebere. Pokud identifier se na interním zásobníku nenajde, nic se nevypíná.

n
(Volitelné) Určuje hodnotu v bajtech, která se má použít pro balení. Pokud není pro modul nastavená možnost /Zp kompilátoru, je výchozí hodnota n 8. Platné hodnoty jsou 1, 2, 4, 8 a 16. Zarovnání člena je na hranici, která je buď násobkem n, nebo násobkem velikosti členu, podle toho, co je menší.

Poznámky

Zabalení třídy spočívá v umístění členů přímo za sebou do paměti. Může to znamenat, že některé nebo všechny členy mohou být zarovnány na hranici menší než výchozí zarovnání cílové architektury. pack poskytuje kontrolu na úrovni deklarace dat. Liší se od možnosti /Zpkompilátoru, která poskytuje pouze řízení na úrovni modulu. balení se projeví na prvním structmístě , unionnebo class prohlášení po jeho výskytu pragma . pack nemá žádný vliv na definice. Volání pack bez argumentů se nenastavuje n na hodnotu nastavenou v možnosti /Zpkompilátoru . Pokud není možnost kompilátoru nastavená, výchozí hodnota je 8 pro x86, ARM a ARM64. Výchozí hodnota je 16 pro nativní platformu x64 a ARM64EC.

Pokud změníte zarovnání struktury, nemusí se v paměti používat tolik místa. Můžete však zaznamenat ztrátu výkonu nebo dokonce získat výjimku vygenerovanou hardwarem pro nerovnaný přístup. Toto chování výjimky můžete upravit pomocí .SetErrorMode

Další informace o úpravě zarovnání najdete v těchto článcích:

  • alignof

  • align

  • __unaligned

  • Příklady zarovnání struktury x64

    Upozorňující

    V sadě Visual Studio 2015 a novějších můžete použít standardní alignas a alignof operátory, na rozdíl od __declspec( align ) __alignof a jsou přenositelné mezi kompilátory. Standard C++ nezabývá balením, takže je nutné použít pack (nebo odpovídající rozšíření u jiných kompilátorů) k určení zarovnání menší než velikost slova cílové architektury.

Příklady

Následující ukázka ukazuje, jak použít packpragma ke změně zarovnání struktury.

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

Následující ukázka ukazuje, jak používat syntaxi push, pop a 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

Viz také

Pragma direktivy a __pragma _Pragma klíčová slova