2016-10-31 3 views
17

ベースが空であるにもかかわらず、複数の継承がオブジェクトのサイズを増やすのはなぜですか?このコードが与えられ

#include <iostream> 

struct A { 

}; 

struct B { 

}; 

struct C { 

}; 

struct E : A { 
    int field; 
}; 

struct F : A, B { 
    int field; 
}; 

struct G : A, B, C { 
    int field; 
}; 

int main() { 
    std::cout << _MSC_VER << std::endl; 
    std::cout << sizeof(E) << std::endl; 
    std::cout << sizeof(F) << std::endl; 
    std::cout << sizeof(G) << std::endl; 
    int o; 
    std::cin >> o; 
    return 0; 
} 

は、私は次の出力が与えられています:

1900 
4 
8 
8 

はなぜFGは、それらのベースが空であっても8の大きさを持っているでしょうか? そして、なぜEのサイズも増えませんか?

Visual Studio Community 2015、バージョン14.0.25431.01 Update 3でこれを構築しています.MSVC++バージョンは明らかに9.0です。

どうしてですか?そのような独特なメモリレイアウトには、どのような根拠がありますか?

+3

なぜバグでしょうか?コンパイラがどの言語ルールに違反していると思いますか? –

+0

@Kerrek標準に違反していないバグでなければ、それは私の質問にも同様に答えます。 –

+2

@KerrekSB「あなたが使っていないものを支払っていない」という非公式のルールかもしれない。私はそれが違反していたと思えば、それは標準にはないが、それは私に関係するだろう。 – Brian

答えて

2

Visual Studio 2015 Update 2は、空の基本クラス最適化のサポートを追加しました。ただし、Updatesはそれらの間でレイアウト互換性があると想定されているため、最適化はデフォルトでオンになっていません。 __declspec(empty_bases)を使用して手動で要求する必要があります。

VCのブログでより多くの情報があります:彼らは、バイナリ互換性を破るために許可されている主要なコンパイラのバージョンの更新を、離すと https://blogs.msdn.microsoft.com/vcblog/2016/03/30/optimizing-the-layout-of-empty-base-classes-in-vs2015-update-2-3/

は、これが最終的にデフォルトになります。

10

char(サイズ1)を除き、特定のタイプが特定のサイズである必要があり、クラスタイプの完全なオブジェクトのサイズがゼロでないという制約が適用されるという言語ルールはありません。あなたの例では、あなたの特定のコンパイラが型をレイアウトする方法についてバグはありません。

新しい質問については、編集した後:MSVCは、複数の継承を最適化するために多大な努力を払っていない可能性があります。これは、払い戻しがほとんどないと主張できる比較的まれなことです。実際の意思決定プロセスについては何も知らないが、このような実用的なエンジニアリングのトレードオフが存在する可能性があると考えてみてください。

+0

空の基底クラス最適化の必要性が[C++/WinRT] https://github.com/Microsoft/cppwinrt)。これはVisual Studio 2015 Update 2から利用可能ですが、デフォルトではオフになっています(すべての変更がバイナリ互換性を破るように)。 – IInspectable

関連する問題