Firstly, I understand byte padding in structs. But I have still a small test contain a double field in struct and I don't know how to explain this :
typedef struct {
char a;
double b;
}data;
typedef struct{
char a;
int b;
}single;
int main(){
printf("%d\n",sizeof(double));
printf("%d\n",sizeof(single));
printf("%d\n",sizeof(data));
}
Through out this test, the answer is : 8
8
and 16
.
Why this result make me thinking ?
By second test, we can see size of word on my machine is 4 bytes.
By first test, we can see size of double is 8 bytes.
So, at the struct data
: the result should be 12 bytes : 4 bytes for char and 8 bytes for double.
But, I don't know why the result is 16 bytes. (So strange with me)
Please explain it for me, thanks :)
The procedure typically used for laying out data in a struct is essentially this:
As Earnest Friedman-Hill stated, the last step adds padding to the end of the struct so that, in an array of them, each struct begins at the required alignment.
So, for a struct such as
struct { char c; double d; int32_t i; }
, on a typical implementation, you have:Observe that the above has nothing to do with any word size of the machine. It only uses the alignment requirement of each member. The alignment requirement can be different for each type, and it can be different from the size of the type, and the above will still work.
(The algorithm breaks if alignment requirements are not powers of two. That could be fixed by making the last step increase the offset to be a multiple of the least common multiple of all the alignments.)
It's sixteen bytes so that if you have an array of
data
s, thedouble
values can all be aligned on 8-byte boundaries. Aligning data properly in memory can make a big difference in performance. Misaligned data can be slower to operate on, and slower to fetch and store.Alignment is up to the compiler unless you explicitly specify it using compiler specific directives.
Variables aren't necessarily word aligned. Sometimes they're double word aligned for efficieny. In the particular case of floating points, they can be aligned to even higher values so that SSE will work.
What is strange to you (or I'm missing something)?
The logic is the same (the padding is according to the "biggest" primitive field in the
struct
(I mean - int, double, char, etc.))As in
single
, you haveit's the same in
data
:which is 16.
The compiler probably aligns all structure sizes to be a multiple of 8