To dlatego, że sizeof
mówi, gdzie zostanie umieszczony następny element tablicy. To znaczy, jeśli masz deklaracji
struct A a[2];
Będziesz potrzebować zarówno a[0].c
i a[1].c
być wyrównane 4096
bajtów.
Ściśle mówiąc kompilator mógł zarządzać tego dokonać o rozmiarze 4096
, ale nie prawdopodobnie dlatego struct A
posiądą wymaganie wyrównania i umieścić dwa int
s przed polem .c
który też musi być wyrównane, który wstawia 4080
ish bajtów wypełnienia między .b
i .c
, a następnie 4080
ish bajtów wypełnienia po .d
.
Sposób, w jaki wykonał to kompilator (bez zmiany układu elementów struktury), ma na celu rozszerzenie koncepcji wyrównania. Zamiast tylko wymagań, że adres musi upaść na adres formularza N*4096
, może rozszerzyć to z przesunięciem wymagającym, aby spadł na adres z formularza N*4096-2*sizeof(int)
. Podanie struct A
takiego wymogu spowodowałoby, że element .c
stałby się naturalnie 4096
wyrównany bajtami bez konieczności wypełniania między .b
i .c
(też).
Kompilator * nie * umożliwia zmianę układu elementów konstrukcyjnych zgodnie z oczekiwaniami. Standard C wymaga, aby wskaźnik do 'a' był także wskaźnikiem do otaczającego obiektu, więc poniższe jest legalne:' int * ptr = &t.a; ((struct A *) ptr) -> b = 42; "Jako takie, kompilator * nie może * zdołać spakować danej struktury w ciągu 4096 bajtów. – cmaster
@cmaster Zmiana kolejności elementów nie jest jedynym sposobem, aby działało z rozmiarem '4096' bajtów. Kompilator może również wymagać, aby 'struct A' musiał mieć adres' 2 * sizeof (int) 'przed granicą' 4096' bajtów. – skyking