Credo che il problema sia che il tuo array è nello stack e che il tuo compilatore è troppo vecchio per supportare le variabili dello stack sovrapposte. GCC 4.6 e versioni successive hanno risolto questo bug .
C11 / C ++ 11 alignas(64) float a[4];
Funziona solo per qualsiasi potenza di 2 allineamento.
Così fa la GNU C __attribute__((aligned(x)))
come la stavi usando.
(In C11, #include <stdalign.h>
per #define alignas _Alignas
: cppref ).
Ma nel tuo caso di un allineamento molto ampio, a un confine di pagina 4k, potresti non volerlo sullo stack.
Poiché il puntatore allo stack potrebbe essere qualsiasi cosa all'avvio della funzione, non è possibile allineare l'array senza allocare molto di più del necessario e regolarlo. (I compilatori useranno and rsp, -4096
o equivalgono e non useranno nessuno dei byte da 0 a 4088 allocati; sarebbe possibile ramificare se quello spazio è abbastanza grande o meno ma non viene fatto perché gli allineamenti enormi sono molto più grandi della dimensione dell'array o di altri locali non sono il caso normale.)
Se sposti l'array fuori dalla funzione e in una variabile globale, dovrebbe funzionare. L'altra cosa che potresti fare è mantenerla come variabile locale (che è un'ottima cosa), ma fallo static
. Ciò impedirà che venga memorizzato nello stack. Attenzione che entrambi questi metodi non sono thread-safe o ricorsivi, poiché ci sarà solo una copia dell'array.
Con questo codice:
#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]);
}
Ho capito:
0x804c000 0x804c004 0x804c008 0x804c00c
che è ciò che ci si aspetta. Con il tuo codice originale, ottengo solo valori casuali come hai fatto tu.