Clang 中的嵌套 C 数组结构对齐

Nested C Array Struct Alignment in Clang

我在使用针对 x64 的 Clang 编译的 C++17 中遇到了一个小内存问题。由于我使用低级内存副本到专用硬件,因此我确实依赖于按预期对齐的内存。我最近从 Visual Studio 转移到 Clang 并遇到了以下问题:

见以下代码:

struct ContainerRoot{};
template<size_t t_size, class t_type>
struct Container : public ContainerRoot
{
    t_type contents[t_size];
};

static_assert(sizeof(Container<1, double>) == 8);           //This works as expected
static_assert(sizeof(Container<4, double>) == 32);          //This works as expected
static_assert(sizeof(Container<16, double>) == 128);        //This works as expected
static_assert(sizeof(Container<4, Container<4, double>>) == 128); //This fails. 

在上面的例子中,sizeof(Container< Container>) 实际上是 136(多了 8 个字节)。我的问题是为什么要添加额外的 8 个字节,我可以避免吗?我很想使用 Clang 编译器,但如果没有解决方法,可能不值得重写围绕将此数据发送到专用硬件的所有代码。

到目前为止,我已经使用 std::is_polymorphic< Container <4, Container<4, double>>>() 进行了检查,只是为了确认没有添加一些虚拟查找 table class。

引用 en.cppreference.com:

The size of any object or member subobject [...] is required to be at least 1 even if the type is an empty class type (that is, a class or struct that has no non-static data members), in order to be able to guarantee that the addresses of distinct objects of the same type are always distinct.

此约束不适用于空碱基(空碱基优化)。

但是,en.cppreference.com 还指出:

Empty base optimization is prohibited if one of the empty base classes is also the type or the base of the type of the first non-static data member, since the two base subobjects of the same type are required to have different addresses within the object representation of the most derived type.

不幸的是,当处理 Container<4, Container<4, double>> 作为第一个成员时,类型为 Container<4, double>,以及 Container<4, Container<4, double>> 都继承自 ContainerRoot

因此我假设 MSVC 在这种情况下实际上是错误的并且过早地应用了它不能做的优化。