为什么多重继承会增加对象的大小,尽管基础是空的?
Why does multiple inheritance increase the size of the object despite the bases being empty?
鉴于此代码:
#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
为什么 F
和 G
的大小是 8
,即使它们的底数是空的?
为什么 E
的大小也不会增加?
我正在使用 Visual Studio Community 2015 版本 14.0.25431.01 Update 3 构建它。MSVC++ 版本显然是 9.0。
怎么会?如此奇特的内存布局有什么道理?
没有语言规则规定任何特定类型都需要具有任何特定大小,char
(大小 1)除外,并且受制于 [=15= 的完整对象的约束] 类型具有非零大小。您的特定编译器在您的示例中布置类型的方式没有任何错误。
至于新问题,在你编辑之后:MSVC 可能只是没有在优化多重继承上投入大量精力,因为这是一个相对罕见的事情,你可以争辩说没有什么回报.我对实际的决策过程一无所知,但考虑到可能存在像这样的实用工程权衡。
Visual Studio 2015 Update 2 添加了对 Empty Base Class 优化的支持。但是,由于更新应该在它们之间是布局兼容的,因此默认情况下不会进行优化;您需要使用 __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/
一旦他们发布了一个主要的编译器版本更新,这最终将成为默认设置,在那里他们被允许破坏二进制兼容性。
鉴于此代码:
#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
为什么 F
和 G
的大小是 8
,即使它们的底数是空的?
为什么 E
的大小也不会增加?
我正在使用 Visual Studio Community 2015 版本 14.0.25431.01 Update 3 构建它。MSVC++ 版本显然是 9.0。
怎么会?如此奇特的内存布局有什么道理?
没有语言规则规定任何特定类型都需要具有任何特定大小,char
(大小 1)除外,并且受制于 [=15= 的完整对象的约束] 类型具有非零大小。您的特定编译器在您的示例中布置类型的方式没有任何错误。
至于新问题,在你编辑之后:MSVC 可能只是没有在优化多重继承上投入大量精力,因为这是一个相对罕见的事情,你可以争辩说没有什么回报.我对实际的决策过程一无所知,但考虑到可能存在像这样的实用工程权衡。
Visual Studio 2015 Update 2 添加了对 Empty Base Class 优化的支持。但是,由于更新应该在它们之间是布局兼容的,因此默认情况下不会进行优化;您需要使用 __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/
一旦他们发布了一个主要的编译器版本更新,这最终将成为默认设置,在那里他们被允许破坏二进制兼容性。