Solución:
La alineación es una restricción sobre las posiciones de memoria que se pueden almacenar en el primer byte de un valor. (Es necesario para mejorar el rendimiento en los procesadores y permitir el uso de ciertas instrucciones que funcionan solo en datos con una alineación particular, por ejemplo, SSE debe alinearse a 16 bytes, mientras que AVX a 32 bytes).
La alineación de 16 significa que las direcciones de memoria que son múltiplos de 16 son las únicas direcciones válidas.
alignas
forzar la alineación al número requerido de bytes. Solo puedes alinear a potencias de 2: 1, 2, 4, 8, 16, 32, 64, 128, …
#include <cstdlib>
#include <iostream>
int main() {
alignas(16) int a[4];
alignas(1024) int b[4];
printf("%pn", a);
printf("%p", b);
}
ejemplo de salida:
0xbfa493e0
0xbfa49000 // note how many more "zeros" now.
// binary equivalent
1011 1111 1010 0100 1001 0011 1110 0000
1011 1111 1010 0100 1001 0000 0000 0000 // every zero is just a extra power of 2
la otra palabra clave
alignof
es muy conveniente, no puedes hacer algo como
int a[4];
assert(a % 16 == 0); // check if alignment is to 16 bytes: WRONG compiler error
pero tu puedes hacer
assert(alignof(a) == 16);
assert(alignof(b) == 1024);
tenga en cuenta que en realidad esto es más estricto que una simple operación “%” (módulo). De hecho, sabemos que algo alineado a 1024 bytes está necesariamente alineado a 1, 2, 4, 8 bytes pero
assert(alignof(b) == 32); // fail.
Entonces, para ser más precisos, “alignof” devuelve la mayor potencia de 2 con la que algo está alineado.
También alignof es una buena manera de conocer de antemano el requisito de alineación mínimo para tipos de datos básicos (probablemente devolverá 1 para caracteres, 4 para flotante, etc.).
Todavía legal:
alignas(alignof(float)) float SqDistance;
Algo con una alineación de 16 se colocará en la siguiente dirección disponible que sea un múltiplo de 16 (puede haber un relleno implícito de la última dirección utilizada).
La alineación no es relleno (aunque a veces se introduce relleno para satisfacer los requisitos de alineación). Es una propiedad intrínseca de tipo C ++. Para ponerlo en standardese (3.11[basic.align]
)
Los tipos de objetos tienen requisitos de alineación (3.9.1, 3.9.2) que imponen restricciones sobre las direcciones en las que se puede asignar un objeto de ese tipo. Una alineación es un valor entero definido por la implementación que representa el número de bytes entre direcciones sucesivas en las que se puede asignar un objeto dado. Un tipo de objeto impone un requisito de alineación a cada objeto de ese tipo; Se puede solicitar una alineación más estricta utilizando el especificador de alineación (7.6.2).
Cada tipo tiene un requisito de alineación. Generalmente, esto es para que se pueda acceder de manera eficiente a las variables del tipo, sin tener que hacer que la CPU genere más de un acceso de lectura / escritura para llegar a cualquier miembro dado del tipo de datos. Además, también asegura una copia eficiente de toda la variable. alignof
devolverá el requisito de alineación para el tipo dado.
alignas
se utiliza para forzar una alineación en un tipo de datos (siempre que no sea menos estricto que lo que alignof
dicho tipo de datos volvería)