继承多个空 类 时了解 gcc/clang 与 msvc2015 之间的不同填充规则
Understanding different padding rules between gcc/clang vs msvc2015 when inheriting multiple empty classes
在 gcc/clang 与 msvc2015 中空 classes 的多重继承方面,我看到了不同的行为。我想知道是否有人知道标准中允许这种差异的内容。
#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继承一个空class时不加字节,但是继承多个时加。 C++ 中是否存在未定义行为?
默认情况下,MSVC 不进行此优化,因此它编译的代码可以与旧版本的编译器 ABI 兼容。但是,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");
在 gcc/clang 与 msvc2015 中空 classes 的多重继承方面,我看到了不同的行为。我想知道是否有人知道标准中允许这种差异的内容。
#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继承一个空class时不加字节,但是继承多个时加。 C++ 中是否存在未定义行为?
默认情况下,MSVC 不进行此优化,因此它编译的代码可以与旧版本的编译器 ABI 兼容。但是,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");