310 votes

#pragma pack effet

Je me demandais si quelqu'un pouvait m'expliquer ce que l' #pragma pack préprocesseur déclaration, et plus important encore, pourquoi vouloir l'utiliser.

J'ai vérifié la page MSDN, qui a donné un aperçu, mais je m'attendais à entendre plus de gens avec de l'expérience. Je l'ai vu dans le code, mais je n'arrive pas à trouver où plus.

554voto

Nick Meyer Points 14502

#pragma pack demande au compilateur de pack membres de structure avec notamment l'alignement. La plupart des compilateurs, lorsque vous déclarez une structure, va insérer un rembourrage entre les membres afin de s'assurer qu'ils correspondent aux adresses appropriées dans la mémoire (en général un multiple du type de la taille). Cela permet d'éviter la dégradation de la performance (ou une erreur pure et simple) sur certaines architectures associées à l'accès aux variables qui ne sont pas alignés correctement. Par exemple, étant donné entiers de 4 octets, et la structure suivante:

struct Test
{
   char AAA;
   int BBB;
   char CCC;
};

Le compilateur pourrait choisir de jeter la structure en mémoire comme ceci:

 Bytes: |  1  |  2  3  4  |  5  6  7  8  |  9  |  10 11 12  |
Member: | AAA |  padding  |  BBB         | CCC |  padding   |

et sizeof(Test) serait de 12, même si elle ne contient que 6 octets de données. L'utilisation la plus courante de cas pour l' #pragma (à ma connaissance), c'est quand travail avec les périphériques matériels où vous devez vous assurer que le compilateur ne pas insérer de rembourrage dans les données et chaque membre suit la précédente. Avec #pragma pack(1), la structure ci-dessus seraient disposés comme ceci:

 Bytes: |  1  |  2  3  4  5  |  6  |
Member: | AAA |     BBB      | CCC |

Et sizeof(Test) serait de 6.

Avec #pragma pack(2), la structure ci-dessus seraient disposés comme ceci:

 Bytes: |  1  |    2    |  3  4  5  6  |  7  |    8    |
Member: | AAA | padding |     BBB      | CCC | padding |

Et sizeof(Test) serait 8.

50voto

nmichaels Points 21955

#pragma est utilisé pour envoyer des non-portable (comme en ce compilateur ne) messages du compilateur. Des choses comme la désactivation de certaines mises en garde et d'emballage des structures sont des raisons communes. La désactivation des avertissements spécifiques est particulièrement utile si vous compilez avec les mises en garde que des erreurs drapeau activé.

#pragma pack est spécifiquement utilisé pour indiquer que la structure d'être emballés ne devrait pas avoir de ses membres alignés. C'est utile lorsque vous avez mappé en mémoire de l'interface à un morceau de matériel et doivent être en mesure de contrôler exactement où les différentes les membres de la structure point. Il n'est notamment pas une bonne optimisation de la vitesse, puisque la plupart des machines sont beaucoup plus rapides à traiter avec des données alignées.

22voto

Jerry Coffin Points 237758

Il indique au compilateur de la frontière pour aligner des objets dans une structure. Par exemple, si j'ai quelque chose comme:

struct foo { 
    char a;
    int b;
};

Typique d'une machine 32 bits, que vous auriez normalement "envie" d'avoir 3 octets de remplissage entre a et b afin b de la terre à une limite de 4 octets pour maximiser sa vitesse d'accès (et c'est ce qui est en général le cas par défaut).

Si, toutefois, vous devez faire correspondre un externe définie structure vous voulez vous assurer que le compilateur dispose votre structure exactement selon cette définition externe. Dans ce cas, vous pouvez donner le compilateur un #pragma pack(1) pour lui dire de ne pas apposer de rembourrage entre les membres -- si la définition de la structure comprend un rembourrage entre les membres, de l'insérer de façon explicite (p. ex., généralement avec des membres nommés unusedN ou ignoreN, ou quelque chose de cet ordre).

8voto

Pontus Gagge Points 12950

Éléments de données (par exemple, des membres de classes et les structures) sont généralement alignés sur WORD ou DWORD les limites de l'actuelle génération de processeurs, afin d'améliorer les temps d'accès. Récupération d'un DWORD à une adresse qui n'est pas divisible par 4, il faut au moins un cycle du PROCESSEUR sur un 32 bits processeur. Donc, si vous avez par exemple trois char membres de l' char a, b, c;, en fait, ils ont tendance à prendre 6 ou 12 octets de stockage.

#pragma vous permet d'outrepasser cette fonction pour obtenir plus efficace l'utilisation de l'espace, au détriment de la vitesse d'accès, ou pour des raisons de cohérence de données entre les différents compilateur cibles. J'ai eu beaucoup de plaisir avec cette transition à partir de 16 bits à 32 bits de code; j'attends le portage 64 bits code provoque le même genre de maux de tête pour un peu de code.

2voto

Clifford Points 29933

Un compilateur peut placer des membres de structure sur les limites d'octets pour des raisons de performance sur une architecture particulière. Cela peut laisser inutilisé rembourrage entre les membres. La Structure de l'emballage, les membres des forces pour être contiguës.

Cela peut être important pour exemple, si vous avez besoin d'une structure pour se conformer à un fichier en particulier ou de communication où les données dont vous avez besoin de données pour être à des positions spécifiques dans une séquence. Cependant, une telle utilisation ne traite pas avec endian-ness, de sorte que, bien utilisé, il peut ne pas être portable.

Il peut aussi exactement la superposition de registre interne de la structure de certains périphériques d'e/S comme un UART ou contrôleur USB par exemple, afin que l'accès de registre par le biais d'une structure plutôt que des adresses directes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X