Buscar..


Introducción

Todos los tipos en C ++ tienen una alineación. Esta es una restricción en la dirección de memoria dentro de la cual se pueden crear objetos de ese tipo. Una dirección de memoria es válida para la creación de un objeto si la división de esa dirección por la alineación del objeto es un número entero.

Las alineaciones de tipo son siempre una potencia de dos (incluido 1).

Observaciones

La norma garantiza lo siguiente:

  • El requisito de alineación de un tipo es un divisor de su tamaño. Por ejemplo, una clase con un tamaño de 16 bytes podría tener una alineación de 1, 2, 4, 8 o 16, pero no 32. (Si los miembros de una clase solo tienen un tamaño de 14 bytes, pero la clase debe tener un requisito de alineación de 8, el compilador insertará 2 bytes de relleno para hacer que el tamaño de la clase sea igual a 16.)
  • Las versiones firmadas y sin firmar de un tipo entero tienen el mismo requisito de alineación.
  • Un puntero para void tiene el mismo requisito de alineación que un puntero para char .
  • Las versiones calificadas para cv y no calificadas para cv de un tipo tienen el mismo requisito de alineación.

Tenga en cuenta que si bien existe alineación en C ++ 03, no fue hasta C ++ 11 que se hizo posible consultar la alineación (usando alignof ) y la alineación de control (utilizando alignas ).

Consultar la alineación de un tipo.

c ++ 11

El requisito de alineación de un tipo se puede consultar utilizando la palabra clave alignof como un operador alignof . El resultado es una expresión constante de tipo std::size_t , es decir, se puede evaluar en tiempo de compilación.

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

Salida posible

El requisito de alineación de int es: 4

Si se aplica a una matriz, produce el requisito de alineación del tipo de elemento. Si se aplica a un tipo de referencia, produce el requisito de alineación del tipo referenciado. (Las referencias en sí mismas no tienen alineación, ya que no son objetos).

Controlando la alineación

C ++ 11

La palabra clave alignas se puede usar para forzar a una variable, miembro de datos de clase, declaración o definición de una clase, o declaración o definición de una enumeración, para tener una alineación particular, si se admite. Se presenta en dos formas:

  • alignas(x) , donde x es una expresión constante, le da a la entidad la alineación x , si es compatible.
  • alignas(T) , donde T es un tipo, le da a la entidad una alineación igual al requisito de alineación de T , es decir, alignof(T) , si es compatible.

Si se aplican múltiples especificadores alignas a la misma entidad, se aplica el más estricto.

En este ejemplo, se garantiza que el búfer buf se alineará adecuadamente para contener un objeto int , aunque su tipo de elemento sea un unsigned char , que puede tener un requisito de alineación más débil.

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

alignas no se puede usar para dar a un tipo una alineación más pequeña que la que tendría el tipo sin esta declaración:

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 , cuando se le da una expresión constante entera, se le debe dar una alineación válida. Las alineaciones válidas son siempre potencias de dos y deben ser mayores que cero. Los compiladores deben admitir todas las alineaciones válidas hasta la alineación del tipo std::max_align_t . Pueden apoyar las alineaciones más grandes que esto, pero el soporte para la asignación de memoria para tales objetos es limitada. El límite superior de las alineaciones depende de la implementación.

C ++ 17 cuenta con soporte directo en operator new para asignar memoria para tipos sobre alineados.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow