Recherche…


Introduction

Tous les types en C ++ ont un alignement. Ceci est une restriction sur l'adresse mémoire que les objets de ce type peuvent être créés à l'intérieur. Une adresse mémoire est valide pour la création d'un objet si la division de cette adresse par l'alignement de l'objet est un nombre entier.

Les alignements de type sont toujours une puissance de deux (dont 1).

Remarques

La norme garantit les éléments suivants:

  • L'exigence d'alignement d'un type est un diviseur de sa taille. Par exemple, une classe avec une taille de 16 octets peut avoir un alignement de 1, 2, 4, 8 ou 16, mais pas de 32. (Si les membres d'une classe ne totalisent que 14 octets, mais que la classe doit avoir un besoin d'alignement) de 8, le compilateur va insérer 2 octets de remplissage pour que la taille de la classe soit égale à 16.)
  • Les versions signées et non signées d'un type entier ont la même exigence d'alignement.
  • Un pointeur à void a la même exigence d'alignement qu'un pointeur sur char .
  • Les versions qualifiées cv et non qualifiées CV d'un type ont la même exigence d'alignement.

Notez que si l'alignement existe en C ++ 03, ce n'est qu'en C ++ 11 qu'il est devenu possible d'interroger l'alignement (en utilisant alignof ) et de contrôler l'alignement (en utilisant alignas ).

Interroger l'alignement d'un type

c ++ 11

L'exigence d'alignement d'un type peut être interrogée à l'aide du mot clé alignof tant qu'opérateur unaire. Le résultat est une expression constante de type std::size_t , c'est-à-dire qu'il peut être évalué au moment de la compilation.

#include <iostream>
int main() {
    std::cout << "The alignment requirement of int is: " << alignof(int) << '\n';
}

Sortie possible

Le besoin d'alignement de int est: 4

Si elle est appliquée à un tableau, elle génère l’alignement requis pour le type d’élément. S'il est appliqué à un type de référence, il génère l'exigence d'alignement du type référencé. (Les références elles-mêmes n'ont aucun alignement, car elles ne sont pas des objets.)

Contrôle de l'alignement

C ++ 11

Le mot-clé alignas peut être utilisé pour forcer une variable, un membre de données de classe, une déclaration ou une définition de classe, ou une déclaration ou une définition d'un enum, à avoir un alignement particulier, s'il est pris en charge. Il se présente sous deux formes:

  • alignas(x) , où x est une expression constante, donne à l'entité l'alignement x , si elle est supportée.
  • alignas(T) , où T est un type, donne à l'entité un alignement égal à l'exigence d'alignement de T , c'est-à-dire alignof(T) , si elle est prise en charge.

Si plusieurs spécificateurs d' alignas sont appliqués à la même entité, le plus strict s'applique.

Dans cet exemple, le tampon buf est correctement aligné pour contenir un objet int , même si son type d'élément est un caractère unsigned char , ce qui peut nécessiter un alignement plus faible.

alignas(int) unsigned char buf[sizeof(int)];
new (buf) int(42);

alignas ne peut pas être utilisé pour donner à un type un alignement plus petit que le type sans cette déclaration:

alignas(1) int i; //Il-formed, unless `int` on this platform is aligned to 1 byte.
alignas(char) int j; //Il-formed, unless `int` has the same or smaller alignment than `char`.

alignas , quand on leur donne une expression constante, doivent recevoir un alignement valide. Les alignements valides sont toujours des puissances de deux et doivent être supérieurs à zéro. Les compilateurs doivent prendre en charge tous les alignements valides jusqu’à l’alignement du type std::max_align_t . Ils peuvent prendre en charge des alignements plus importants, mais la prise en charge de l'allocation de mémoire pour ces objets est limitée. La limite supérieure des alignements dépend de l'implémentation.

C ++ 17 dispose d'un support direct dans l' operator new pour allouer de la mémoire aux types sur-alignés.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow