2011-12-07 22 views
5

MSDNによると、/Zpコマンドのデフォルトは8で、64ビットの境界線の境界が使用されます。私はいつも32ビットアプリケーションでは、MSVCコンパイラは32ビット境界を使用すると仮定してきました。そのようなMSVCのデフォルトメモリアライメント8

struct Test 
{ 
    char foo; 
    int bar; 
}; 

コンパイラの意志パッド、それは:たとえば/Zp8がデフォルトで使用されているので

struct Test 
{ 
    char foo; 
    char padding[3]; 
    int bar; 
}; 

そう、それは私のパディングは上記と同じ例を使用して7 + 4バイトになりどういう意味します:

struct Test 
{ 
    char foo; 
    char padding1[7]; 
    int bar; 
    char padding2[4]; 
}; // Structure has 16 bytes, ending on an 8-byte boundary 

これは少しばかげていませんか?私は誤解していますか?なぜこのような大きな詰め物が使われているのか、それは空間の浪費のようです。 32ビットシステムのほとんどのタイプは64ビットを使用することさえありませんので、変数の大部分はパディング(おそらく80%以上)を持つでしょう。

+0

あなたは '7 + 4'で明確になりますか?私はちょっと今のところ疑問に混乱しています。 – Mysticial

+0

@Mysticial:別の例を使って私のOPを更新しました。混乱させて申し訳ありません。 –

+0

清算していただきありがとうございます。私はちょうどあなたの最初の構造体をテストし、サイズは2番目の構造体スニペットを介して埋め込まれたわずか8バイトです。だから私はあなたが得ているものを再現することができません。 (または少なくともあなたが得るべきだと思うもの) – Mysticial

答えて

8

これは動作しません。メンバーは、そのサイズの倍数に整列します。 Charから1バイト、2に短い、intから4、2から8までです。構造体が配列内で使用されているときにメンバが正しく位置合わせされるように、構造体は最後にパディングされます。

8のパッキングは、8より大きいメンバーのアラインメントを停止することを意味します。実際の制限であるメモリアロケータは、8よりも揃ったアドレスを返しません。適切に整列され、キャッシュラインを跨いで終わる。しかし、それ以外の場合は、SIMDコードを書くと頭痛がでて、16バイトの整列が必要です。

+0

したがって、MSDNによればデフォルトの配置が8であるため、OP内の最後のコードスニペットは配置パディングの外観ですか?そうでない場合は、説明してください。 –

+1

@Robert:最後のコードが間違っています。これは 'char fooのようにパディングされます。パッド[3]; int bar; 'int 'は構造体の中で最大のメンバーです。あなたはHansが言ったことを非常に慎重に読むべきです – Benjamin

3

これは、すべてのメンバーが8バイトの境界に位置合わせされていることを意味しません。もう少し慎重にお読みください:

the smaller member type or n-byte boundaries 

ここでのキーは、最初の部分 - 「小さいメンバータイプ」です。これは、整列の少ないメンバーが効果的に整列する可能性があることを意味します。

struct x { 
    char c; 
    int y; 
}; 
std::cout << sizeof(x); 
std::cout << "offsetof(x, c) = " << offsetof(x, c) << '\n'; 
std::cout << "offsetof(x, c) = " << offsetof(x, y) << '\n'; 

これは、実際には、intは4バイトアライメントにのみパディングであることを意味する8、0、4-生み出します。

+1

答えの最後の部分が間違っています。構造体からintを削除し、sizeof()が8を返さないことに注意してください。 –