为什么空基类优化不起作用?

Meh*_*dad 14 c++ optimization visual-c++ empty-class

为什么在Visual C++中没有完全应用空基类优化(EBO)?

如果我有很多基类,有什么办法让我帮助编译器进行这种优化吗?

#include <iostream>

struct T1 { };
struct T2 { };
struct T3 { };
struct T4 { };
struct T5 { };
struct T6 { };

struct Test : T1, T2, T3, T4, T5, T6 { };

int main() { std::cout << sizeof(Test); }   // Prints 5
Run Code Online (Sandbox Code Playgroud)

Jam*_*lis 18

这是Visual C++编译器中长期存在的错误.当一个类派生自多个空基类时,只使用空基本优化(EBO)优化初始空基类.

2006年Microsoft Connect上报告了此问题: 空基本优化无法正常工作. 目前,Microsoft Connect上不会显示旧错误.我被告知这是一个临时问题,但我不知道什么时候会解决.与此同时,以下是对Jonathan Caves的错误的回应,Jonathan Caves是Visual C++编译器团队的开发人员之一:

嗨:不幸的是,即使这是Visual C++对象模型中的一个错误,我们也无法在此时修复它,因为修复它可能会破坏很多现有程序,因为对象的大小会发生变化.希望将来我们可以解决这个问题,但不能解决产品的下一个版本问题.

感谢您报告此问题.

  • 这在VS2017中仍然是一个问题。但是,可以根据此[blog post](https://blogs.msdn.microsoft.com/vcblog/2016/03/30/optimizing-the-layout-of-empty-base- classes-in-vs2015-update-2-3 /)。从VS2015 Update 2开始,可以将__declspec(empty_bases)添加到派生类声明中,以在多个继承场景中强制实施EBO。必须手动完成此操作以保持二进制兼容性。 (2认同)

Nec*_*lis 8

"官方"的立场是MSVC只会进行单一继承的EBO,不幸的是MS声明了这个声明的错误报告,所以剩下的就是MSDN上一个较旧的问题,指出它并引用现在删除的错误报告.


Tob*_*obi 6

Visual Studio 2017 Update 2 开始有一个修复程序......但默认情况下它是禁用的。您必须分别为每个类显式启用它:

    struct __declspec(empty_bases) Test : T1, T2, T3, T4, T5, T6 { };
    //     ^^^^^^^^^^^^^^^^^^^^^^^

    static_assert(1 == sizeof(Test));
Run Code Online (Sandbox Code Playgroud)

可悲的是,这仍然适用于真实的,即使/std:c++latest/permissive-甚至在Visual Studio中2019:没有统一设置它的方式。