pack
pragma
Gibt die Verpackungsausrichtung für Struktur-, Vereinigungs- und Klassenmausrichtung an.
Syntax
#pragma pack( show )
#pragma pack( push
[ ] [,
,
identifier
n
])
#pragma pack( pop
[ {,
identifier
|n
} ])
#pragma pack(
[n
])
Parameter
show
(Optional) Zeigt den aktuellen Bytewert für die Verpackungsausrichtung an. Der Wert wird von einer Warnmeldung angezeigt.
push
(Optional) Verschiebt den aktuellen Verpackungsausrichtungswert auf den internen Compilerstapel und legt den aktuellen Ausrichtungswert für verpackungen auf n fest. Wenn n nicht angegeben ist, wird der aktuelle Verpackungsausrichtungswert verschoben.
pop
(Optional) Entfernt den Datensatz vom anfang des internen Compilerstapels. Wenn "n " nicht angegeben pop
ist, ist der dem resultierenden Datensatz am Anfang des Stapels zugeordnete Verpackungswert der neue Verpackungsausrichtungswert. Wenn z. B. n angegeben wird, #pragma pack(pop, 16)
wird n zum neuen Verpackungsausrichtungswert. Wenn Sie z. B. ein identifier
Popup verwenden, werden alle Datensätze im Stapel eingeblentet, #pragma pack(pop, r1)
bis der Datensatz identifier
gefunden wird. Dieser Datensatz wird eingetaucht, und der Verpackungswert, der mit dem Datensatz verknüpft ist, der oben im Stapel gefunden wird, wird zum neuen Verpackungsausrichtungswert. Wenn Sie einen identifier
Eintrag verwenden, der in keinem Datensatz im Stapel gefunden wird, wird dies pop
ignoriert.
Die Anweisung #pragma pack (pop, r1, 2)
entspricht #pragma pack (pop, r1)
dem gefolgt von #pragma pack(2)
.
identifier
(Optional) Bei Verwendung mit push
, weist dem Datensatz im internen Compilerstapel einen Namen zu. Bei Verwendung mit pop
, werden Datensätze aus dem internen Stapel angezeigt, bis identifier
sie entfernt werden. Wenn identifier
der interne Stapel nicht gefunden wird, wird nichts angezeigt.
n
(Optional) Gibt den Wert in Byte an, der für die Verpackung verwendet werden soll. Wenn die Compileroption /Zp
für das Modul nicht festgelegt ist, lautet der Standardwert n
8. Gültige Werte sind 1, 2, 4, 8 und 16. Die Ausrichtung eines Elements befindet sich auf einer Grenze, die entweder ein Vielfaches von n
oder ein Vielfaches der Größe des Elements ist, je nachdem, was kleiner ist.
Hinweise
Um eine Klasse zu packen , besteht darin, die Mitglieder direkt hintereinander im Arbeitsspeicher zu platzieren. Dies kann bedeuten, dass einige oder alle Elemente an einer Grenze ausgerichtet werden können, die kleiner als die Standardausrichtung der Zielarchitektur ist. pack
ermöglicht die Steuerung auf Datendeklarationsebene. Sie unterscheidet sich von der Compileroption /Zp
, die nur Steuerelement auf Modulebene bereitstellt. Das Pack wird bei der ersten struct
union
, oder class
Deklaration nach dem Erkennen des pragma Pakets wirksam. pack
hat keine Auswirkungen auf Definitionen. Das Aufrufen pack
ohne Argumente wird auf den Wert festgelegt, der in der Compileroption /Zp
festgelegt n
ist. Wenn die Compileroption nicht festgelegt ist, ist der Standardwert 8 für x86, ARM und ARM64. Der Standardwert ist 16 für systemeigene x64 und ARM64EC.
Wenn Sie die Ausrichtung einer Struktur ändern, wird möglicherweise nicht so viel Speicherplatz im Arbeitsspeicher verwendet. Möglicherweise wird jedoch ein Leistungsverlust angezeigt oder sogar eine hardwaregenerierte Ausnahme für den nicht ausgerichteten Zugriff angezeigt. Sie können dieses Ausnahmeverhalten mithilfe von SetErrorMode
.
Weitere Informationen zum Ändern der Ausrichtung finden Sie in den folgenden Artikeln:
Beispiele für die x64-Strukturausrichtung
Warnung
In Visual Studio 2015 und höher können Sie die Standard
alignas
- undalignof
Operatoren verwenden, die im Gegensatz zu__alignof
__declspec( align )
compilerübergreifend portierbar sind. Der C++-Standard adressiert nicht das Packen, daher müssen Sie weiterhin (oder die entsprechende Erweiterung auf anderen Compilern) verwendenpack
, um Ausrichtungen anzugeben, die kleiner als die Wortgröße der Zielarchitektur sind.
Beispiele
Im folgenden Beispiel wird gezeigt, wie sie die pack
pragma Ausrichtung einer Struktur ändern.
// 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
Das folgende Beispiel zeigt, wie Sie die Syntax für Push, Pop und Show verwenden.
// 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