7

サンプルコード

#include <iostream>

struct base {};

template<typename Type>
struct left : base {

   Type value;
};

template<typename Type>
struct right : base {

   Type value;
}; 

int main() {
   std::cout << "sizeof left<base> = " << sizeof(left<base>) << std::endl;
   std::cout << "sizeof left<right<base>>    = " << sizeof(left<right<base>>) << std::endl;
   std::cout << "sizeof left<right<left<right<left<base>>>>> = " << sizeof(left<right<left<right<left<base>>>>>) << std::endl;
}

出力

GCC4.6では

sizeof left<base> = 2  
sizeof left<right<base>>    = 3  
sizeof left<right<left<right<left<base>>>>> = 6

clang3.1を使用

sizeof left<base> = 2  
sizeof left<right<base>>    = 3  
sizeof left<right<left<right<left<base>>>>> = 6

MSVC2012を使用

sizeof left<base> = 1
sizeof left<right<base>>    = 1
sizeof left<right<left<right<left<base>>>>> = 1

それで、質問は、それがGCC / clangのバグなのか、それとも実装定義なのか、それとも正しい出力なのか(標準からの引用、またはそのような振る舞いの説明がいいでしょう)

4

2 に答える 2

3

関連する引用は 1.8 [intro.object] パラグラフ 6 です。

オブジェクトがビットフィールドまたはサイズがゼロの基本クラスのサブオブジェクトでない限り、そのオブジェクトのアドレスは、それが占有する最初のバイトのアドレスです。ビット フィールドではない 2 つのオブジェクトは、一方が他方のサブオブジェクトである場合、または少なくとも 1 つがサイズ 0 の基本クラス サブオブジェクトであり、それらが異なる型である場合、同じアドレスを持つことができます。それ以外の場合、それらは別個のアドレスを持つものとします。

あなたのright<T>andleft<T>オブジェクトには(なぜ異なるクラステンプレートが必要なのですか?1つで十分なはずです)、それぞれvalue(タイプのT)メンバーがあります。それぞれが固有のアドレスを取得する必要があります。したがって、

sizeof(left<right<left<right<left<base>>>>>) == 1

絶対に間違っている!6 つの異なるオブジェクトがあります。

  • 5value
  • 1left<right<left<right<left<base>>>>>

left<right<left<right<left<base>>>>>そのサブジェクトの 1 つ (value他のルールを思い出せば最初のもの) だけがアドレスを共有できます。つまり、オブジェクトのサイズは少なくとも 5 である必要があります。オブジェクトは整列されたときに最適に機能するため、6 バイトにパディングされるようです (これは奇妙です。4 の倍数にパディングされると予想されます)。

のサイズも同じではありleft<base>ません1:base既に 2 つのオブジェクトが関係しています! base` オブジェクトの基底クラスの形式の 1 つはlef<base> and one in form of a member of this class. These two個別のアドレスを必要とするため、サイズは少なくとも 2 である必要があります。

いずれにせよ、オブジェクトのサイズには、少なくともどれだけ大きいかという要件しかありません。彼らは何かよりも大きくしてはならないという要件はありません。これは、実装の品質の問題と見なされます。これに基づいて、間違っている唯一のコンパイラ (サイズの引用符が実際に正しいと仮定) は MSVC++ です。他のサイズは、希望よりも若干大きい場合がありますが、これはエラーではありません。

于 2012-11-22T06:49:02.400 に答える
0

GCCの動作は奇妙ですが、 sizeof は完全にコンパイラの問題であるため、コンパイラがどのように試してみるかに依存するだけです

#pragma pack(1) 

そして結果をもう一度見る

于 2012-11-22T06:35:41.410 に答える