Visual C++ では、コンパイラ スイッチ ( /Zp
) と、pack
構造体メンバーの配置に影響を与えるプラグマの両方が提供されています。しかし、私はそれらがどのように機能するかについて、いくつかの誤解を持っているようです。
MSDNによると、特定のアライメント値 n に対して、
メンバーの位置合わせは、n の倍数またはメンバーのサイズの倍数のいずれか小さい方の境界上にあります。
pack 値が 8 バイト (デフォルト) であるとします。構造体内では、サイズが 8 バイト未満のメンバーは、それ自体のサイズの倍数のオフセットになると思います。サイズが 8 バイト以上のメンバーは、8 バイトの倍数のオフセットになります。
次に、次のプログラムを実行します。
#include <tchar.h>
#pragma pack(8)
struct Foo {
int i1;
int i2;
char c;
};
struct Bar {
char c;
Foo foo;
};
int _tmain(int argc, _TCHAR* argv[]) {
int fooSize = sizeof(Foo); // yields 12
Bar bar;
int fooOffset = ((int) &bar.foo) - ((int) &bar); // yields 4
return 0;
}
構造体のFoo
サイズは 12 バイトです。したがって、メンバーは実際にはオフセット 4 にあるのに、オフセット 8 (8 の倍数) にあるBar
と予想されます。なぜですか?Foo
また、Foo
実際には 4+4+1 = 9 バイトのデータしかありません。コンパイラは、最後にパディング バイトを自動的に追加します。しかし、再び、8 バイトのアラインメント値が与えられた場合、4 ではなく 8 の倍数にパディングすべきではないでしょうか?
説明をいただければ幸いです。