How to use pragma pack?

4

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

    
asked by thc 02.05.2018 в 00:19
source

1 answer

5
  

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

    
answered by 02.05.2018 в 18:58