I recently found this code
#pragma pack(push)
#pragma pack(2)
I do not understand very well how to use this pre-processor directive although from what I see it is directly related to the structures
I recently found this code
#pragma pack(push)
#pragma pack(2)
I do not understand very well how to use this pre-processor directive although from what I see it is directly related to the structures
In summary: It serves to align the elements of the structures.
It is a series of C preprocessor instructions that allow you to specify the alignment of structures, for example:
struct Prueba {
int a; char b;
};
If the size of% co_of% is 4 and that of% co_of% is 1, the value returned by% co_of% is 8, why? Because the alignment is dependent on the size of the word in the architecture to which it is compiled, so int
can end in 8, or even 32 bytes.
+----+----+----+----+----+----+----+----+
| FF | FF | FF | FF | 00 | Relleno. |
+----+----+----+----+----+----+----+----+
| Prueba.a; | .b | Nada |
+----+----+----+----+----+----+----+----+
Is 8 because it is aligned to the limits of an integer ( char
) of 4 bytes, if sizeof(struct Prueba)
were sizeof(struct Prueba)
, then int
outside 16.
Prueba.a
comes to solve that issue 1 :
uint64_t
: Stacks the previous value in an internal stack to align the fields of the structures. sizeof(struct Prueba)
: Stacks the previous value in the internal stack to align the fields of the structures and then adjusts the new value to align the fields. #pragma pack
: Adjust the value to align the fields without further. #pragma pack(push)
: Adjust the value to align the fields of the structures to the last one used. When using #pragma pack(push, valor)
after #pragma pack(N)
what we do is simple, we tell the compiler:
Hey! Try that all structures are aligned for a minimum of N bytes, but before, save the previous value to restore it later.
I mean, something like ...
| Alineamiento normal o por defecto |
+----+----+----+----+----+----+----+----+
| FF | FF | FF | FF | 00 | Relleno. |
+----+----+----+----+----+----+----+----+
| Prueba.a; | .b | Nada |
+----+----+----+----+----+----+----+----+
| Con #pragma(2) |
+----+----+----+----+----+----+
| FF | FF | FF | FF | 00 | XX |
+----+----+----+----+----+----+
| Prueba.a; | .b | -- |
+----+----+----+----+----+----+
It's really not that nice ...
Advantages of doing
#pragma pack(pop)
: The essential is that you save a few bytes. The main problem is that the reading is usually slow, in addition to creating a pointer of an element within the structure, we would not have a valid pointer 2 (Not quite true, according to I) .
Sample code 3 :
#include <stdio.h>
int main(void) {
struct Prueba1 {
int a; char b;
} A;
printf("Antes de:\n\t#pragma pack(push)\n\t#pragma pack(2) - ");
printf("%zu == 8\n", sizeof(struct Prueba1));
#pragma pack(push)
#pragma pack(2)
struct Prueba2 {
int a; char b;
} B;
#pragma pack(pop)
printf("Luego de:\n\t#pragma pack(push)\n\t#pragma pack(2) - ");
printf("%zu == 6\n", sizeof(struct Prueba2));
return 0;
}
Print respectively:
Antes de:
#pragma pack(push)
#pragma pack(2) - 8 == 8
Luego de:
#pragma pack(push)
#pragma pack(2) - 6 == 6
1 : These #pragma pack(N)
s exist for compatibility with the windows compilers, according to GCC. See: Structure-Packing Pragmas .
2 : link
3 : < a href="https://ideone.com/tH2jOe"> ideone