Saya percaya masalahnya adalah bahwa array Anda ada di tumpukan, dan kompiler Anda terlalu tua untuk mendukung variabel tumpukan yang terlalu selaras. GCC 4.6 dan yang lebih baru memperbaiki bug itu .
C11 / C ++ 11 alignas(64) float a[4];
Hanya Berfungsi untuk semua kekuatan dari 2 keselarasan.
Begitu juga GNU C __attribute__((aligned(x)))
saat Anda menggunakannya.
(Di C11, #include <stdalign.h>
untuk #define alignas _Alignas
: cppref ).
Namun dalam kasus perataan yang sangat besar, ke batas halaman 4k, Anda mungkin tidak menginginkannya di tumpukan.
Karena penunjuk tumpukan bisa berupa apa saja saat fungsi dimulai, tidak ada cara untuk menyelaraskan array tanpa mengalokasikan lebih banyak dari yang Anda butuhkan dan menyesuaikannya. (Kompiler akan and rsp, -4096
atau setara dan tidak menggunakan salah satu dari 0 hingga 4088 byte yang dialokasikan; bercabang pada apakah ruang itu cukup besar atau tidak akan dimungkinkan tetapi tidak dilakukan karena perataan besar jauh lebih besar daripada ukuran array atau penduduk setempat lainnya bukan kasus normal.)
Jika Anda memindahkan array dari fungsi dan menjadi variabel global, itu akan berfungsi. Hal lain yang dapat Anda lakukan adalah menyimpannya sebagai variabel lokal (yang merupakan hal yang sangat bagus), tetapi buatlah static
. Ini akan mencegahnya disimpan di tumpukan. Berhati-hatilah karena kedua cara ini tidak aman untuk thread atau rekursi-aman, karena hanya akan ada satu salinan larik.
Dengan kode ini:
#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]);
}
Saya mengerti ini:
0x804c000 0x804c004 0x804c008 0x804c00c
itulah yang diharapkan. Dengan kode asli Anda, saya hanya mendapatkan nilai acak seperti yang Anda lakukan.