I'm trying to get my head around the whole structure padding thing. I know that it helps the CPU to read data from memory in words, but the issue I'm having is how the data members are aligned.
I read an article[1] that basically said if the structure is divisible by 4, the structure is aligned. Here's a quote:
"For example, if you have 1 char variable (1-byte) and 1 int variable (4-byte) in a struct, the compiler will pads 3 bytes between these two variables. Therefore, the total size of this struct variable is 8 bytes, instead of 5 bytes. By doing this, the address of this struct data is divisible evenly by 4."
Based on the latter quote, I came to this:
1 2 3 4 5 6
// A
struct Data
{
char A;
int B;
};
The compiler will insert 3-bytes between A and B so that A is properly aligned to B. The structure is divisible by 4.
1 2 3 4 5 6
// B
struct Data
{
int A;
char B;
};
The compiler will add 3-bytes between A and B so that B is aligned to A. The structure is again divisible by 4.
So, in general, if the size of A is greater than B, B is aligned to A. If the size of A is smaller than B, A is aligned to B.
Am I right on this? I get the sneaky suspicion that I'm not, because I swear these grey hairs weren't here before.
It appears that they're indicating that the struct gets aligned to the largest data member of the the struct.
The struct (or union, class) member variables must be aligned to the highest bytes of the size of any member variables to prevent performance penalties.
So in:
1 2 3 4 5 6 7
// A
struct Data
{
char A;
// 3 bytes of padding
int B; // Aligned to B (4 bytes)
};
And:
1 2 3 4 5 6 7
// B
struct Data
{
int A; // Aligned to A (4 bytes)
char B;
// 3 bytes of padding
};
OK, that's confirmed, then. In example B, is the padding inserted after B or before it? For example:
1 2 3 4 5 6 7 8
// B
struct Data
{
int A;
// 3-Bytes padding here?...
char B;
// ...or here?
};
Songho wrote:
The struct (or union, class) member variables must be aligned to the highest bytes of the size of any member variables to prevent performance penalties.
So what about this:
1 2 3 4 5 6 7 8 9
// C
struct Data
{
char A;
// 3-Bytes...
int B;
// ?-Bytes...
double C;
};
My compiler yields 16-bytes for the size of example C, which leads me to believe that there's no padding between B and C. Hmmm...
I got the impression that the padding was inserted after, but looking at it again, I think I was looking at the misaligned data picture there, so...I'm not sure that that's really very well covered.
As far as example C, since it's aligning to 8, and without the specificity of when the data gets padded, I suppose that there could be any combination of padding, incl.:
3,0,0,0
2,1,0,0
2,0,1,0
2,0,0,1
1,1,1,0
1,1,0,1
1,0,1,1
etc...
Not sure. I can't see anything definitive in the article one way or the other about whether or not the determination can be made. From my end, it would be speculation.
01353378 (Space between char and int is 4 -- Padding is AFTER char)
0135337C (Space between int and int is 4 -- No padding)
01353380
0135336C (Space between int and char is 4 -- No padding)
01353370 (Space between char and int is 4 -- Padding AFTER char)
01353374
Press any key to continue . . .