Creo que el problema es que su matriz está en la pila y que su compilador es demasiado antiguo para admitir variables de pila sobrealineadas. GCC 4.6 y posteriores corrigieron ese error .
C11 / C ++ 11 alignas(64) float a[4];
simplemente funciona para cualquier potencia de 2 alineación.
También lo hace GNU C __attribute__((aligned(x)))
tal como lo estaba usando.
(En C11, #include <stdalign.h>
para #define alignas _Alignas
: cppref ).
Pero en su caso de una alineación muy grande, a un límite de página de 4k, es posible que no lo desee en la pila.
Debido a que el puntero de pila puede ser cualquier cosa cuando se inicia la función, no hay forma de alinear la matriz sin asignar mucho más de lo necesario y ajustarlo. (Los compiladores usarán and rsp, -4096
o su equivalente y no usarán ninguno de los 0 a 4088 bytes que se asignaron; la ramificación sobre si ese espacio es lo suficientemente grande o no sería posible, pero no se hace porque las alineaciones enormes son mucho más grandes que el tamaño de la matriz u otros valores locales no son el caso normal.)
Si mueve la matriz de la función a una variable global, debería funcionar. La otra cosa que podría hacer es mantenerla como una variable local (lo cual es muy bueno), pero hágalo static
. Esto evitará que se almacene en la pila. Tenga en cuenta que ambas formas no son seguras para subprocesos o recursividad, ya que solo habrá una copia de la matriz.
Con este código:
#include <stdio.h>
float a[4] __attribute__((aligned(0x1000))) = {1.0, 2.0, 3.0, 4.0};
int
main(void)
{
printf("%p %p %p %p\n", &a[0], &a[1], &a[2], &a[3]);
}
Entiendo esto:
0x804c000 0x804c004 0x804c008 0x804c00c
que es lo que se espera. Con tu código original, obtengo valores aleatorios como tú.