私はこのプログラムでコンパイラーの間にいくつかの矛盾を発見しました、
struct A {
};
struct B : public A {
float m;
};
struct C : public A {
B b;
float n;
};
struct D : public A {
float n;
B b;
};
static_assert(sizeof(A) == 1, "");
static_assert(sizeof(B) == 4, "");
static_assert(sizeof(C) == 8, ""); // most compilers say this is 12
static_assert(sizeof(D) == 8, "");
ほとんどのコンパイラは、sizeof(C)== 8で、sizeof(C)は実際には12であると主張します。私が見つけた唯一のコンパイラはそうではなく、8であると言っているのはMicrosoft VisualStudio2010です。
私より賢い人から言われた理由は、B内にAの2つの別個の参照があり、互いに異なる個々のオフセットを保持する必要があるためです。まず、Cから派生したAはオフセット0にあり、メンバーb内の2番目のAは0の最初のAと同じオフセットにすることはできないため、4バイトのパディングが挿入されます。
ほとんどのコンパイラはこの動作を実装しているので、両方のAが異なる参照を持っていることを確認するためにどのような場合が必要か疑問に思いました。なぜこれが当てはまるのかについての直感をお探しですか?
誰かがそれが規格によって要求される条件であるかもしれないと言いました、そして、我々はそれの理由が何であるかについて興味がありましたか?
ありがとうございました