子对象的对齐小于基对象的对齐

Alignment of Child is Smaller Than Alignment of Base

本文关键字:对齐 对象 小于      更新时间:2023-10-16

经过深思熟虑,我将一个问题简化为以下简单示例:

//__declspec(align(16)) class Vec4 {}; //For testing purposes on Windows
//class Vec4 {} __attribute__((__aligned__(16))); //For testing purposes on *nix
class Base { public:
    Vec4 v; //16-byte-aligned struct
};
class Child : public Base {};
static_assert(alignof( Base)>=16,"Check 1");
static_assert(alignof(Child)>=16,"Check 2");

检查1次通过;检查2失败我的问题:为什么


在实践中,分配Child(即new Child)将导致v可能与8字节对齐(v使用SSE,因此这反过来会导致崩溃)。

编译器是"英特尔编译器2016"。我试过g++和Clang,它们看起来不错。这可能是编译器错误吗?

我已直接询问英特尔。虽然最初他们的团队可以复制,但几天后就不可能了。我和他们都没有解释。所以,魔法确实存在,而且没有造成任何伤害。

至于问题的实际内容:是的,似乎子项的对齐应该至少与基项的对齐一样大,而不这样做的编译器是错误的。

N.B.堆栈分配尊重类的alignof,但malloc/new不尊重(他们怎么知道呢?)。正如另一个答案所说,必须使用自定义堆分配器。这个问题与正确的alignof本身是分开的。

根据http://en.cppreference.com/w/cpp/language/object#Alignment:

如果新表达式、std::allocater::allocate和std::get_temporary_buffer支持对齐的类型,那么它就是实现定义的。允许使用过对齐类型实例化的分配器在编译时无法实例化,在运行时抛出std::bad_alloc,静默地忽略不支持的对齐要求,或正确处理它们。

作为一种变通方法,我建议为基类定义自定义operator new