Je pense que le problème est que votre tableau est sur la pile et que votre compilateur est trop ancien pour prendre en charge des variables de pile suralignées. GCC 4.6 et versions ultérieures ont corrigé ce bogue .
C11 / C ++ 11 alignas(64) float a[4];
Fonctionne juste pour toute puissance d'alignement 2.
Il en va de même pour le GNU C __attribute__((aligned(x)))
tel que vous l'utilisiez.
(En C11, #include <stdalign.h>
pour le #define alignas _Alignas
: cppref ).
Mais dans votre cas d'un très grand alignement, à une limite de 4k pages, vous ne voudrez peut-être pas qu'il soit sur la pile.
Étant donné que le pointeur de pile peut être n'importe quoi au démarrage de la fonction, il n'y a aucun moyen d'aligner le tableau sans allouer beaucoup plus que ce dont vous avez besoin et l'ajuster. (Les compilateurs and rsp, -4096
ou l'équivalent et n'utiliseront aucun des 0 à 4088 octets alloués; il serait possible de déterminer si cet espace est suffisamment grand ou non, mais n'est pas fait car d'énormes alignements beaucoup plus grands que la taille du tableau ou d'autres locaux ne sont pas le cas normal.)
Si vous déplacez le tableau hors de la fonction et dans une variable globale, cela devrait fonctionner. L'autre chose que vous pouvez faire est de la conserver en tant que variable locale (ce qui est une très bonne chose), mais faites-la static
. Cela l'empêchera d'être stocké sur la pile. Sachez que ces deux méthodes ne sont pas sécurisées pour les threads ou la récursivité, car il n'y aura qu'une seule copie du tableau.
Avec ce code:
#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]);
}
J'ai compris:
0x804c000 0x804c004 0x804c008 0x804c00c
ce qui est attendu. Avec votre code d'origine, j'obtiens juste des valeurs aléatoires comme vous l'avez fait.