子对象的对齐小于基对象的对齐
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,因此这反过来会导致崩溃)。
编译器是"英特尔编译器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
。
相关文章:
- 哪些值存储在对齐的结构/类对象的填充字节中
- 如何分配适合容纳 T 类型对象的缓冲区(可能过度对齐、可能有运算符 new 等)
- 对象地址是否保证是其类型对齐的倍数
- MIPS 和 x86_64 之间的对象对齐差异
- Sizeof 舍入到对齐方式,但编译器仍将对象放在剩余的字节中
- 自动热键:重新映射 MS Visio 的快捷方式,以将手动选择的对象对齐到顶部(好像按:"AlignTop")
- 在以下情况下,是否可以分配未对齐的对象?
- 如何分配内存对齐C++对象数组?
- STD :: Aligned_Storage如何正确对齐任何对象的存储
- std::可选和提升::可选是否尊重托管对象的对齐限制?
- 如何强制对齐堆分配的对象
- 将对象位置与网格对齐
- 对象数组对齐与 __attribute__aligned() 或 alignas()
- 对象数组作为链表中的字符数组 - 我对对齐的假设是否有效
- 如何使用指针合法地访问对齐错误的对象
- 我不明白在下面的代码中将 char buffer[] 与 X 类型的对象对齐的原因
- 标准是否要求自动存储中的对象对任何类型都具有正确的对齐方式(例如malloc)
- xcode中的对象字节对齐
- 子对象的对齐小于基对象的对齐
- 具有对齐成员的对象的动态分配-可能的解决方案