5

MSDNによると、/Zpコマンドのデフォルトは8です。これは、64ビットのアライメント境界が使用されることを意味します。私は常に、32ビットアプリケーションの場合、MSVCコンパイラは32ビット境界を使用すると想定していました。例えば:

struct Test
{
   char foo;
   int bar;
};

コンパイラは次のようにパディングします。

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

つまり、/Zp8はデフォルトで使用されているので、上記の同じ例を使用すると、パディングが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%以上)。

4

2 に答える 2

10

それはそれがどのように機能するかではありません。メンバーは、そのサイズの倍数に配置されます。Char を 1 バイトに、short を 2 に、int を 4 に、double を 8 に変換します。構造体が配列で使用されている場合にメンバーが正しく配置されるように、構造体の最後にパディングが行われます。

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

于 2011-12-07T05:14:08.840 に答える
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';

これは 8, 0, 4- を生成します。つまり、実際には 4intバイト アラインメントにのみパディングされます。

于 2011-12-07T04:55:06.103 に答える