我试图了解填充如何在32位编译器中工作。我把它归结为以下示例代码:
#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;
}
该程序的输出是:
122 /*actual*/
124 /*actual*/
我的期望是
124 /*expectation*/
126 /*expectation */
现在,据我所知,如果有任何必要的填充,它应该在INNER结构中。即INNER结构应填写如下:
typedef struct {
ushort a;
ushort b[60];
ushort compiler_pad; /* I believe compiler should have done this */
}
但相反,我认为编译器正在执行以下操作:
typedef struct{
uchar z;
INNER x;
uchar compiler_pad; /* I believe compiler is doing this */
}OUTER;
有谁知道为什么父结构被填充,而不是纠正内部结构的对齐?
其他细节: - sizeof(uchar)是1 - sizeof(ushort)是2 - 我在32位处理器上,对齐是4 - 我已经检查了this问题
答案 0 :(得分:3)
INNER
连续有61个ushort
个标量,完全符合122个字节; 当自己分配时,它不需要任何填充。这就是INNER
内没有填充的原因。
OUTER
包含一个uchar
(根据定义,的大小为1 ),然后是61 ushort
个。 ushort
的硬件对齐要求是2,而不是1,因此编译器必须在uchar
和61 ushort
之间插入一个填充字节,即之前的 > INNER
对象,以满足它们的对齐要求。如您所料,INNER
的 end 的填充不会安排INNER
在OUTER
内正确对齐。
编辑:编译器在 z
和x
之间插入填充,而不是 OUTER
:
typedef struct {
uchar z;
uchar compiler_pad;
INNER x;
} OUTER;
您可以在程序顶部添加#include <stddef.h>
,然后打印offsetof(OUTER, x)
,以便自行确认。打印的数字为2。