2016-04-02 10 views
2

私はこのコードを持っている: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]; 
     }; 

そして: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; 
} 

そして出力:

516 
16 
8 
512, 516 
1: 448 
2: 464 
3: 480 
4: 496 

は、サイズが516バイトである理由(それは512でなければなりません)? パーティション1のオフセットが448ではないのはなぜですか? どうすれば修正できますか?

+0

どのコンパイラ? – Macmade

+2

余分なパディングを削除するには** packed **という属性を構造体に追加する必要があるかもしれないと思います。 – Vikyboss

+1

パディング。 http://stackoverflow.com/a/18654110/12711 –

答えて

7

パディングバイトまたはパディングビットがある可能性があるためです。 N1570 6.7.2.1 Structure and union specifiersから引用

:(強調鉱山)構造オブジェクト内

15、非ビットフィールドメンバーとビットフィールドが順に増加アドレスを持つ存在 た単位 彼らは宣言されています。適切に が変換された構造オブジェクトへのポインタは、その最初のメンバ(またはそのメンバが ビットフィールドである場合はそれが存在するユニット)を指し、その逆の場合も同様です。 ストラクチャオブジェクトに名前のないパディングがありますが、先頭にはない可能性があります。