Reputation: 437
I am trying to understand how padding works in a 32 bit compiler. I have boiled it down to the following sample code:
#include <stdio.h>
#define uchar unsigned char
#define ushort unsigned short
typedef struct {
ushort a;
ushort b[60];
} INNER;
typedef struct{
uchar z;
INNER x;
}OUTER;
int main(void) {
printf("%d\n",sizeof(INNER));
printf("%d",sizeof(OUTER));
return 0;
}
And the output of this program is:
122 /*actual*/
124 /*actual*/
My expectation however is
124 /*expectation*/
126 /*expectation */
Now, as far as I understand, if there was any padding that was necessary, it should have been in the INNER structure. i.e. INNER structure should have been padded as follows:
typedef struct {
ushort a;
ushort b[60];
ushort compiler_pad; /* I believe compiler should have done this */
}
But instead, I think compiler is doing the following:
typedef struct{
uchar z;
INNER x;
uchar compiler_pad; /* I believe compiler is doing this */
}OUTER;
Does anyone know why the parent structure is being padded, instead of correcting the alignment of inner structure?
Additional details: - sizeof(uchar) is 1 - sizeof(ushort) is 2 - I am on a 32 bit processor and alignment is 4 - I have already checked this question
Upvotes: 1
Views: 226
Reputation: 140445
INNER
is 61 ushort
scalars in a row, which fits exactly into 122 bytes; when allocated by itself, it doesn't require any padding. That is why there is no padding inside an INNER
.
OUTER
, however, consists of one uchar
(whose size is 1 by definition) and then 61 ushort
s. The hardware alignment requirement for ushort
is 2, not 1, so the compiler must insert one byte of padding between the uchar
and the 61 ushort
s, i.e. before the INNER
object, so that their alignment requirement is satisfied. Padding at the end of the INNER
as you expected would not arrange for INNER
to be properly aligned within OUTER
.
EDIT: The compiler is inserting padding in between z
and x
, not at the end of OUTER
:
typedef struct {
uchar z;
uchar compiler_pad;
INNER x;
} OUTER;
You can confirm this for yourself by adding #include <stddef.h>
at the top of your program and then printing offsetof(OUTER, x)
. The number printed will be 2.
Upvotes: 3