GCC生成错误的结构偏移量为什么?

kry*_*115 2 c gcc

我有这个代码:

mbr.h:

struct mbr_partition {
                char flags;
                char start_head;
                char start_sector;
                char start_cyl;
                char type;
                char last_head;
                char last_sector;
                char last_cyl;
                uint32_t start;
                uint32_t size;
        };

        struct mbr {
                char bootloader[446];
                struct mbr_partition partition1;
                struct mbr_partition partition2;
                struct mbr_partition partition3;
                struct mbr_partition partition4;
                char magic[2];
        };
Run Code Online (Sandbox Code Playgroud)

并且:main.c:

int main()
{
        printf("%d\n", sizeof(struct mbr));
        printf("%d\n", sizeof(struct mbr_partition));
        printf("%d\n", sizeof(long));
        struct mbr mbr;
        printf("%d, %d\n", ((char *) &mbr.magic) - ((char *) &mbr), sizeof(mbr)$
        printf("1: %d\n", ((char *) &mbr.partition1) - ((char *) &mbr));
        printf("2: %d\n", ((char *) &mbr.partition2) - ((char *) &mbr));
        printf("3: %d\n", ((char *) &mbr.partition3) - ((char *) &mbr));
        printf("4: %d\n", ((char *) &mbr.partition4) - ((char *) &mbr));
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

并输出:

516
16
8
512, 516
1: 448
2: 464
3: 480
4: 496
Run Code Online (Sandbox Code Playgroud)

为什么大小是516字节(应该是512)?为什么partition1偏移是448而不是446?我该如何解决?

nal*_*zok 7

因为可能存在一些填充字节或填充位.

引自N1570 6.7.2.1 Structure and union specifiers:(强调我的)

15在结构对象中,非位字段成员和位字段所在的单元具有按声明顺序增加的地址.指向适当转换的结构对象的指针指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然. 结构对象中可能存在未命名的填充,但不是在其开头.