Reputation: 322
This is my test code:
#include <cstdio>
struct A {
int a;
int b;
int c __attribute__((aligned(4096)));
int d;
}t;
int main()
{
printf("%d\n",sizeof(t));
return 0;
}
The result is 8192, but I can't figure out the reason.
Upvotes: 11
Views: 1955
Reputation: 14390
It's because sizeof
tells where the next element in an array would be placed. That is if you have the declaration
struct A a[2];
You would need both a[0].c
and a[1].c
to be aligned at 4096
bytes.
Strictly speaking the compiler could manage to make this happen with a size of 4096
, but it doesn't probably because struct A
will inherit the alignment requirement and put two int
s before the .c
field which too has to be aligned which inserts 4080
ish bytes of padding between .b
and .c
and then 4080
ish bytes of padding after .d
.
The way the compiler could have done this (without rearranging struct members) is to extend the concept of alignment. Instead of just having requirements that the address must fall on an address of the form N*4096
it could extend this with an offset requiring it to fall on an adress of the form N*4096-2*sizeof(int)
. Giving struct A
such a requirement would result in that the .c
element would naturally become 4096
bytes aligned without requiring padding between the .b
and .c
(too).
Upvotes: 4
Reputation: 98328
There are a few facts about alignment in structs that are worth mentioning:
So, since one of these members has an alignment of 4096, the alignment of the struct itself is at least 4096. It will most likely be exactly that.
But since it needs a padding of 4080 bytes before c
, the size of the struct is at least 4104, but it must be a multple of 4096, its alignment. So it grows to 8192.
Upvotes: 12