Child 的对齐小于 Base 的对齐

Alignment of Child is Smaller Than Alignment of Base

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

//__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 ,因此这反过来会导致崩溃)。

编译器是Intel Compiler 2016,我试过g++和Clang,好像还可以。这可能是编译器错误吗?

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

It is implementation-defined if new-expression, std::allocator::allocate, and std::get_temporary_buffer support over-aligned types. Allocators instantiated with over-aligned types are allowed to fail to instantiate at compile time, to throw std::bad_alloc at runtime, to silently ignore unsupported alignment requirement, or to handle them correctly.

作为解决方法,我建议为您的基础 class.

定义自定义 operator new

我有 asked Intel directly. Although it could initially be reproduced by their team, after a few days, it couldn't be. Neither I nor they had an explanation. So, magic 确实存在,没有造成任何伤害。

至于问题的实际内容:是的,看来 child 的对齐应该至少与基的对齐一样大,不这样做的编译器是错误。

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