#efecto paquete pragma
Me preguntaba si alguien podría explicarme qué #pragma pack
hace la declaración del preprocesador y, lo que es más importante, por qué querríamos utilizarla.
Revisé la página de MSDN , que ofrecía información, pero esperaba escuchar más de personas con experiencia. Lo he visto en código antes, aunque parece que ya no puedo encontrar dónde.
#pragma pack
Le indica al compilador que empaquete los miembros de la estructura con una alineación particular. La mayoría de los compiladores, cuando declara una estructura, insertarán relleno entre los miembros para garantizar que estén alineados con las direcciones apropiadas en la memoria (generalmente un múltiplo del tamaño del tipo). Esto evita la penalización de rendimiento (o error absoluto) en algunas arquitecturas asociadas con el acceso a variables que no están alineadas correctamente. Por ejemplo, dados enteros de 4 bytes y la siguiente estructura:
struct Test
{
char AA;
int BB;
char CC;
};
El compilador podría optar por diseñar la estructura en la memoria de esta manera:
| 1 | 2 | 3 | 4 |
| AA(1) | pad.................. |
| BB(1) | BB(2) | BB(3) | BB(4) |
| CC(1) | pad.................. |
y sizeof(Test)
sería 4 × 3 = 12, aunque solo contenga 6 bytes de datos. El caso de uso más común para #pragma
(que yo sepa) es cuando se trabaja con dispositivos de hardware donde es necesario asegurarse de que el compilador no inserte relleno en los datos y que cada miembro siga al anterior. Con #pragma pack(1)
, la estructura anterior se presentaría así:
| 1 |
| AA(1) |
| BB(1) |
| BB(2) |
| BB(3) |
| BB(4) |
| CC(1) |
Y sizeof(Test)
sería 1×6 = 6.
Con #pragma pack(2)
, la estructura anterior se presentaría así:
| 1 | 2 |
| AA(1) | pad.. |
| BB(1) | BB(2) |
| BB(3) | BB(4) |
| CC(1) | pad.. |
Y sizeof(Test)
sería 2 × 4 = 8.
El orden de las variables en la estructura también es importante. Con variables ordenadas de la siguiente manera:
struct Test
{
char AA;
char CC;
int BB;
};
y con #pragma pack(2)
, la estructura quedaría así:
| 1 | 2 |
| AA(1) | CC(1) |
| BB(1) | BB(2) |
| BB(3) | BB(4) |
y sizeOf(Test)
sería 3 × 2 = 6.
#pragma
se utiliza para enviar mensajes no portátiles (como en este compilador únicamente) al compilador. Cosas como desactivar ciertas advertencias y estructuras de embalaje son razones comunes. Deshabilitar advertencias específicas es particularmente útil si compila con el indicador de advertencias como errores activado.
#pragma pack
específicamente se usa para indicar que la estructura que se está empaquetando no debe tener sus miembros alineados. Es útil cuando tiene una interfaz asignada en memoria a una pieza de hardware y necesita poder controlar exactamente hacia dónde apuntan los diferentes miembros de la estructura. En particular, no es una buena optimización de la velocidad, ya que la mayoría de las máquinas son mucho más rápidas a la hora de manejar datos alineados.
Para deshacer después envuélvalo #pragma pack(push,1)
y#pragma pack(pop)