Pat*_*ick 7 c++ c++-standard-library visual-studio
在 Visual Studio 中,编译 64 位时:
sizeof(std::max_align_t) 是 8__STDCPP_DEFAULT_NEW_ALIGNMENT__ 是 16因此,尽管std::max_align_t表示 的实现new应该返回对齐到 8 个字节的倍数的指针,但对齐要求为 16 个字节的分配不会调用该void* operator new (std::size_t count, std::align_val_t);方法,而是调用void* operator new (std::size_t count);(参见https://en.cppreference.com/w/cpp/memory /new/operator_new ) 并期望它们返回一个 16 字节对齐的指针。
所以分配一个这样定义的结构:
struct alignas(16) S {double m_value;};
Run Code Online (Sandbox Code Playgroud)
将调用标准运算符new(不带std::align_val_t参数)并期望它在 16 个字节上对齐,而std::max_align_t只指定它应该在 8 个字节上对齐。
这意味着当否决new运算符时,您必须将所有内容对齐至少 16 个字节,即使 8 个字节就足够了。
C++17 中有两层过度对齐的类型:extended 和 new-extended。std::max_align_t定义未扩展__STDCPP_DEFAULT_NEW_ALIGNMENT__的最大对齐,并定义未新扩展的最大对齐。
顾名思义,新扩展对齐是关于你用new.
基本上,常规operator new将返回适合任何对象的内存,直到新扩展的对齐大小。任何更大的对齐都更喜欢使用operator new指定正在创建的类型的对齐方式的重载。当然,就像一般的过度对齐类型一样,有条件地支持。operator delete销毁与此类类型关联的内存的调用也是如此。
Visual Studio 所说的是不被视为过度对齐的最大对齐是 8 字节,但分配的内存对齐operator new是 16 字节。
这意味着当否决
new运算符时,您必须将所有内容对齐至少 16 个字节,即使 8 个字节就足够了。
基本上,是的。没有办法要求实现告诉您原始operator new/delete重载所请求的对齐方式。
现在,您可以逐个对象地重载该对象operator new以operator new直接调用特定于对齐的对齐方式。但是你不能让编译器这样做。