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。
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 在这种情况下实际上是错误的并且过早地应用了它不能做的优化。
我在使用针对 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。
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 在这种情况下实际上是错误的并且过早地应用了它不能做的优化。