pack
pragma
Specifica l'allineamento della compressione per i membri della struttura, dell'unione e della classe.
Sintassi
#pragma pack( show )
#pragma pack( push
[,
identifier
] [,
n
])
#pragma pack( pop
[,
{identifier
|n
} ])
#pragma pack(
[n
])
Parametri
show
(Facoltativo) Visualizza il valore di byte corrente per l'allineamento della compressione. Il valore viene visualizzato da un messaggio di avviso.
push
(Facoltativo) Inserisce il valore di allineamento della compressione corrente nello stack interno del compilatore e imposta il valore di allineamento della compressione corrente su n. Se n non viene specificato, viene eseguito il push del valore di allineamento di compressione corrente.
pop
(Facoltativo) Rimuove il record dalla parte superiore dello stack del compilatore interno. Se n non è specificato con pop
, il valore di compressione associato al record risultante nella parte superiore dello stack è il nuovo valore di allineamento della compressione. Se n viene specificato, ad esempio , #pragma pack(pop, 16)
n diventa il nuovo valore di allineamento della compressione. Se si utilizza , identifier
ad esempio , #pragma pack(pop, r1)
vengono visualizzati tutti i record nello stack fino a quando identifier
non viene trovato il record. Il record viene estratto e il valore di compressione associato al record trovato nella parte superiore dello stack diventa il nuovo valore di allineamento della compressione. Se si usa un oggetto identifier
che non viene trovato in alcun record nello stack, l'oggetto pop
viene ignorato.
L'istruzione #pragma pack (pop, r1, 2)
è equivalente a #pragma pack (pop, r1)
seguita da #pragma pack(2)
.
identifier
(Facoltativo) Se usato con push
, assegna un nome al record nello stack del compilatore interno. Se usato con pop
, i record vengono visualizzati dallo stack interno fino a identifier
quando non viene rimosso. Se identifier
non viene trovato nello stack interno, non viene visualizzato nulla.
n
(Facoltativo) Specifica il valore, in byte, da utilizzare per la compressione. Se l'opzione /Zp
del compilatore non è impostata per il modulo, il valore predefinito per n
è 8. Tra i valori validi sono compresi 1, 2, 4, 8 e 16. L'allineamento di un membro si trova su un limite che è un multiplo di n
o un multiplo delle dimensioni del membro, a seconda delle dimensioni.
Osservazioni:
Per comprimere una classe è posizionare i relativi membri direttamente dopo l'uno dopo l'altro in memoria. Può significare che alcuni o tutti i membri possono essere allineati su un limite inferiore rispetto all'allineamento predefinito dell'architettura di destinazione. pack
fornisce il controllo a livello di dichiarazione dei dati. Differisce dall'opzione /Zp
del compilatore , che fornisce solo il controllo a livello di modulo. pack ha effetto alla prima struct
dichiarazione , union
o class
dopo che pragma viene visualizzato . pack
non ha alcun effetto sulle definizioni. La chiamata pack
a senza argomenti imposta n
sul valore impostato nell'opzione /Zp
del compilatore . Se l'opzione del compilatore non è impostata, il valore predefinito è 8 per x86, ARM e ARM64. Il valore predefinito è 16 per x64 nativo e ARM64EC.
Se si modifica l'allineamento di una struttura, potrebbe non usare lo spazio in memoria. Tuttavia, potrebbe verificarsi una perdita di prestazioni o persino ottenere un'eccezione generata dall'hardware per l'accesso non idoneo. È possibile modificare questo comportamento di eccezione usando SetErrorMode
.
Per altre informazioni su come modificare l'allineamento, vedere gli articoli seguenti:
Esempi di allineamento della struttura x64
Avviso
In Visual Studio 2015 e versioni successive è possibile usare gli operatori e
alignof
standardalignas
, che a differenza__alignof
di e__declspec( align )
sono portabili tra i compilatori. Lo standard C++ non risolve la compressione, quindi è comunque necessario usarepack
(o l'estensione corrispondente in altri compilatori) per specificare allineamenti inferiori alle dimensioni delle parole dell'architettura di destinazione.
Esempi
Nell'esempio seguente viene illustrato come usare per pack
pragma modificare l'allineamento di una struttura.
// 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'esempio seguente illustra come usare la sintassi push, pop e 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