Code 1:-
struct emp
{
char a;
double b;
};
int main()
{
struct emp e;
printf("%p %p", (void*)&e.a, (void*)&e.b);
}
Output on my computer:-
OO28FF00 0028FF08
As the size of char
and double
is '1' and '8' respectively and hence the 0028FF00
and 0028FF08
are multiples of '1' and '8' respectively.
Code 2:-
struct emp
{
char a;
long double b;
};
int main()
{
struct emp e;
printf("%p %p \n", (void*)&e.a,(void*)&e.b);
}
The output is :-
0028FF00 0028FF04
As the size of char
and long double
is '1' and '12' respectively but 0028FF04
is not a multiple of '12'.
Why padding is not applied in this case?
A long double
is an 80 bit floating point so you need 10 bytes. 10 is really not a very good size though, thus Intel 32 bit processors decided on 12 bytes. 12 is a multiple of 4 which represents 32 bits (3 x 32 bits). This is considered aligned because a 32 bit processor only needs 4 bytes alignment, so the 12 bytes is aligned at any 4 bytes boundary. Obviously, the compiler knows what it's doing and it always tries to generate the smallest possible structure.
This being said, this is where you see that you cannot use a struct declaration and hope to save it as is in a file... at least not with the default C types (you can use int32_t, uint64_t, etc. to get exactly what you want, but there is no equivalent for floating point numbers...)
As someone commented, on a 64 bit architecture, long double is 16 bytes. A waste of 6 bytes... but it makes the type 64 bit aligned all the time.