pack
pragma
Hiermee geeft u de uitlijning van de verpakking voor structuur, samenvoeging en klasseleden.
Syntaxis
#pragma pack( show )
#pragma pack( push
[,
identifier
] [,
n
])
#pragma pack( pop
[,
{identifier
|n
} ])
#pragma pack(
[n
])
Parameters
show
(Optioneel) Geeft de huidige bytewaarde weer voor het uitlijnen van de verpakking. De waarde wordt weergegeven met een waarschuwingsbericht.
push
(Optioneel) Pusht de huidige uitlijningswaarde van de verpakking op de interne compilerstack en stelt de huidige uitlijningswaarde in op n. Als n niet is opgegeven, wordt de huidige waarde voor de uitlijning van de verpakking gepusht.
pop
(Optioneel) Hiermee verwijdert u de record boven aan de interne compilerstack. Als n niet is opgegeven met pop
, is de verpakkingswaarde die is gekoppeld aan de resulterende record boven aan de stapel de nieuwe uitlijningswaarde voor de verpakking. Als n is opgegeven, bijvoorbeeld #pragma pack(pop, 16)
, wordt n de nieuwe uitlijningswaarde voor de verpakking. Als u een identifier
gebruikt, bijvoorbeeld #pragma pack(pop, r1)
, worden alle records op de stapel weergegeven totdat de record met identifier
is gevonden. Deze record wordt gepopt en de verpakkingswaarde die is gekoppeld aan de record die boven aan de stapel wordt gevonden, wordt de nieuwe uitlijningswaarde voor het inpakken. Als u een identifier
gebruikt die niet in een record op de stapel staat, wordt de pop
genegeerd.
De instructie #pragma pack (pop, r1, 2)
is gelijk aan #pragma pack (pop, r1)
gevolgd door #pragma pack(2)
.
identifier
(Optioneel) Wanneer deze wordt gebruikt met push
, wijst u een naam toe aan de record op de interne compilerstack. Wanneer deze wordt gebruikt met pop
, worden records van de interne stack verwijderd totdat identifier
wordt verwijderd. Als identifier
niet wordt gevonden op de interne stack, wordt er niets weergegeven.
n
(Optioneel) Hiermee geeft u de waarde in bytes die moet worden gebruikt voor verpakking. Als de compileroptie /Zp
niet is ingesteld voor de module, is de standaardwaarde voor n
8. Geldige waarden zijn 1, 2, 4, 8 en 16. De uitlijning van een lid bevindt zich op een grens die een veelvoud van n
is of een veelvoud van de grootte van het lid, afhankelijk van wat kleiner is.
Opmerkingen
Als u inpakken een klas de leden direct na elkaar in het geheugen wilt plaatsen. Dit kan betekenen dat sommige of alle leden kunnen worden uitgelijnd op een grens die kleiner is dan de standaarduitlijning van de doelarchitectuur.
pack
geeft controle op gegevensdeclaratieniveau. Het verschilt van de compileroptie /Zp
, die alleen besturingselement op moduleniveau biedt.
pack van kracht wordt bij de eerste struct
, union
of class
verklaring nadat de pragma is gezien.
pack
heeft geen effect op definities. Als u pack
aanroept zonder argumenten, wordt n
ingesteld op de waarde die is ingesteld in de compileroptie /Zp
. Als de compileroptie niet is ingesteld, is de standaardwaarde 8 voor x86, ARM en ARM64. De standaardwaarde is 16 voor x64 native en ARM64EC.
Als u de uitlijning van een structuur wijzigt, wordt mogelijk niet zoveel ruimte in het geheugen gebruikt. Mogelijk ziet u echter een verlies van prestaties of krijgt u zelfs een door hardware gegenereerde uitzondering voor niet-uitgelijnde toegang. U kunt dit uitzonderingsgedrag wijzigen met behulp van SetErrorMode
.
Zie de volgende artikelen voor meer informatie over het wijzigen van de uitlijning:
x64-structuuruitlijningsvoorbeelden
Waarschuwing
In Visual Studio 2015 en hoger kunt u de standaardoperators
alignas
enalignof
gebruiken, die in tegenstelling tot__alignof
en__declspec( align )
overdraagbaar zijn tussen compilers. De C++-standaard bevat geen adresverpakking, dus u moet nog steedspack
(of de bijbehorende extensie op andere compilers) gebruiken om uitlijningen op te geven die kleiner zijn dan de woordgrootte van de doelarchitectuur.
Voorbeelden
In het volgende voorbeeld ziet u hoe u de pack
pragma gebruikt om de uitlijning van een structuur te wijzigen.
// 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
In het volgende voorbeeld ziet u hoe u de push-, pop-gebruikt en syntaxis weergeeft.
// 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