Question

Par exemple, si je déclare une variable longue, puis-je supposer qu'elle sera toujours alignée sur un "sizeof (long)" frontière? L'aide en ligne de Microsoft Visual C ++ le dit, mais s'agit-il d'un comportement standard?

plus d'infos:

a. Il est possible de créer explicitement un entier mal aligné (* barre):

  

char foo [5]

     

int * bar = (int *) (& amp; foo [1]);

b. Apparemment, #pragma pack () n’affecte que les structures, les classes et les unions.

c. La documentation MSVC indique que les types de POD sont alignés sur leurs tailles respectives (mais est-ce toujours ou par défaut, et s'agit-il d'un comportement standard, je ne sais pas)

Était-ce utile?

La solution

Comme d'autres l'ont mentionné, cela ne fait pas partie de la norme et est laissé au compilateur à mettre en œuvre à sa guise pour le processeur en question. Par exemple, VC pourrait facilement implémenter des exigences d’alignement différentes pour un processeur ARM et pour les processeurs x86.

Microsoft VC implémente ce que l’on appelle en principe l’alignement naturel jusqu’à la taille spécifiée par la directive #pragma pack ou l’option de ligne de commande / Zp. Cela signifie que, par exemple, tout type de POD de taille inférieure ou égale à 8 octets sera aligné en fonction de sa taille. Tout ce qui est plus grand sera aligné sur une limite de 8 octets.

S'il est important de contrôler l'alignement pour différents processeurs et différents compilateurs, vous pouvez utiliser une taille d'emballage de 1 et remplir vos structures.

#pragma pack(push)
#pragma pack(1)    
struct Example
{
   short data1;     // offset 0
   short padding1;  // offset 2
   long data2;      // offset 4
};
#pragma pack(pop)

Dans ce code, la variable padding1 existe uniquement pour vous assurer que les données2 sont alignées naturellement.

Réponse à a:

Oui, cela peut facilement provoquer des données mal alignées. Sur un processeur x86, cela ne fait pas vraiment mal. Sur d’autres processeurs, cela peut entraîner un blocage ou une exécution très lente. Par exemple, le processeur Alpha lèverait une exception de processeur qui serait capturée par le système d'exploitation. Le système d'exploitation inspecte ensuite l'instruction, puis effectue le travail nécessaire pour gérer les données mal alignées. Puis l'exécution continue. Le mot clé __ unaligned peut être utilisé dans VC pour marquer un accès non aligné pour des programmes non x86 (c'est-à-dire pour CE).

Autres conseils

Par défaut, oui. Cependant, il peut être modifié via le pack () #pragma.

Je ne crois pas que la norme C ++ impose des exigences à cet égard et laisse le soin à la mise en œuvre.

C et C ++ n'imposent aucun type d'alignement. Cependant, l'alignement naturel est fortement préféré par x86 et requis par la plupart des autres architectures de CPU, et les compilateurs font généralement tout leur possible pour satisfaire leurs processeurs. Donc, dans la pratique, vous ne verrez pas un compilateur générer des données mal alignées à moins de le tordre vraiment.

Oui, tous les types sont toujours alignés au moins sur leurs exigences d'alignement.

Comment pourrait-il en être autrement?

Notez cependant que le type sizeof () n'est pas identique à l'alignement.

Vous pouvez utiliser la macro suivante pour déterminer les exigences d'alignement d'un type:

#define ALIGNMENT_OF( t ) offsetof( struct { char x; t test; }, test )

Dépend du compilateur, des pragmas et du niveau d’optimisation. Avec les compilateurs modernes, vous pouvez également choisir l'optimisation du temps ou de l'espace, ce qui pourrait également modifier l'alignement des types.

Généralement, ce sera parce que lire / écrire est plus rapide de cette façon. Mais presque tous les compilateurs ont un commutateur pour le désactiver. Dans gcc sa -malign - ???. Avec les agrégats, ils sont généralement alignés et dimensionnés en fonction des exigences d’alignement de chaque élément.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top