在继承多个空类

时间:2018-04-01 03:46:01

标签: c++ struct multiple-inheritance

在gcc / clang vs msvc2015中,当涉及到多个空类继承时,我看到了不同的行为。我想知道是否有人会知道标准中允许这种差异的原因。

#include <cstdint>
using namespace std;

class Empty1 {};
static_assert(sizeof(Empty1) == 1, "Expected size of 1 for Empty1");

class Empty2 {};
static_assert(sizeof(Empty2) == 1, "Expected size of 1 for Empty2");

class Empty3 : Empty2, Empty1 {};
static_assert(sizeof(Empty3) == 1, "Expected size of 1 for Empty3");

class Int1 { uint32_t i; };
static_assert(sizeof(Int1) == 4, "Expected size of 4 for Int1");

class Int2 : Empty1 { uint32_t i; };
static_assert(sizeof(Int2) == 4, "Expected size of 4 for Int2");

class Int3 : Empty2 { uint32_t i; };
static_assert(sizeof(Int3) == 4, "Expected size of 4 for Int3");

class Int4 : Empty3 { uint32_t i; };
static_assert(sizeof(Int4) == 8, "Expected size of 8 for Int4");
static_assert(sizeof(Int4) == 4, "Expected size of 4 for Int4");

此代码在msvc2015上生成:

error C2338: Expected size of 4 for Int4

虽然gcc和clang生成了这个:

error: static_assert failed "Expected size of 8 for Int4"

换句话说,msvc2015在从空类继承时不会添加任何字节,但在从多个继承时会这样做。在C ++中是未定义的行为吗?

1 个答案:

答案 0 :(得分:2)

默认情况下,MSVC不会执行此优化,因此它编译的代码可以与旧版本的编译器兼容。但是,if you use __declspec(empty_bases),您可以告诉MSVC启用此优化:

#ifdef _MSC_VER
#define EBO_ENABLE __declspec(empty_bases)
#else
#define EBO_ENABLE
#endif

class EBO_ENABLE Empty3 : Empty2, Empty1 {};
static_assert(sizeof(Empty3) == 1, "Expected size of 1 for Empty3");

Live on Godbolt