Compartir a través de


pack pragma

Especifica la alineación de empaquetado de los miembros de estructura, unión y clase.

Sintaxis

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

Parámetros

show
(Opcional) Muestra el valor de byte actual de la alineación de empaquetado. El valor se muestra mediante un mensaje de advertencia.

push
(Opcional) Inserta el valor de alineación de empaquetado actual en la pila interna del compilador y establece el valor actual de alineación de empaquetado en n. Si no se especifica n, se inserta el valor actual de alineación de empaquetado.

pop
(Opcional) Quita el registro de la parte superior de la pila interna del compilador. Si no se especifica n con pop, el valor de empaquetado asociado al registro resultante en la parte superior de la pila es el nuevo valor de alineación de empaquetado. Si se especifica n, por ejemplo, #pragma pack(pop, 16), n se convierte en el nuevo valor de alineación de empaquetado. Si saca con un identifier, por ejemplo, #pragma pack(pop, r1), se sacan todos los registros de la pila hasta encontrar el que tiene identifier. Ese registro se saca y el valor de empaquetado asociado al registro encontrado en la parte superior de la pila es el nuevo valor de alineación de empaquetado. Si saca con un identifier que no se encuentra en ningún registro de la pila, pop se omite.

La instrucción #pragma pack (pop, r1, 2) es equivalente a #pragma pack (pop, r1) seguida de #pragma pack(2).

identifier
(Opcional) Cuando se usa con push, asigna un nombre al registro en la pila interna del compilador. Cuando se usa con pop, saca los registros de la pila interna hasta que se quita identifier. Si no se encuentra identifier en la pila interna, no se saca nada.

n
(Opcional) Especifica el valor, en bytes, que se va a usar para el empaquetado. Si no se establece la opción del compilador /Zp para el módulo, el valor predeterminado de n es 8. Los valores válidos son 1, 2, 4, 8 y 16. La alineación de un miembro está en un límite que es múltiplo de n o múltiplo del tamaño del miembro, el que sea menor.

Comentarios

Empaquetar una clase es colocar sus miembros uno detrás de otro en la memoria. Puede significar que algunos o todos los miembros se alineen según un límite menor que la alineación predeterminada de la arquitectura de destino. pack proporciona control en el nivel de declaración de datos. Esto difiere de la opción del compilador /Zp, que solo proporciona control en el nivel de módulo. pack se aplica en la primera declaración struct, union o class tras la detección de pragma. pack no tiene ningún efecto en las definiciones. Una llamada a pack sin argumentos establece n en el valor establecido en la opción del compilador /Zp. Si no se establece la opción del compilador, el valor predeterminado es 8 en x86, ARM y ARM64. El valor predeterminado es 16 en x64 nativo y ARM64EC.

Si cambia la alineación de una estructura, puede que no se use tanto espacio en memoria. Pero es posible que note una pérdida de rendimiento o incluso que reciba una excepción generada por el hardware de acceso no alineado. Puede modificar este comportamiento de excepción mediante SetErrorMode.

Para obtener más información sobre cómo modificar la alineación, vea estos artículos:

  • alignof

  • align

  • __unaligned

  • Ejemplos de alineación de estructuras x64

    Advertencia

    En Visual Studio 2015 y posterior puede usar los operadores estándar alignas y alignof, que, a diferencia de __alignof y __declspec( align ), son portátiles entre compiladores. El estándar C++ no se ocupa del empaquetado, por lo que debe seguir usando pack (o la extensión que corresponda en otros compiladores) para especificar alineaciones que sean inferiores al tamaño de palabra de la arquitectura de destino.

Ejemplos

En el ejemplo siguiente se muestra cómo usar packpragma para cambiar la alineación de una estructura.

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

En el siguiente ejemplo se muestra cómo usar la sintaxis push, pop y 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

Consulte también

Pragmadirectivas y las __pragma palabras clave y _Pragma