Skip to content

Commit 2a1d21f

Browse files
committed
book: add C++17 aligned new for over-aligned types
Extend 9.4 with dynamic allocation of over-aligned types: C++17 added operator new/delete overloads taking std::align_val_t, so new respects alignof for over-aligned types. Compiled example code/9/9.4. Refs #1
1 parent 3ab6142 commit 2a1d21f

3 files changed

Lines changed: 56 additions & 0 deletions

File tree

‎book/en-us/09-others.md‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,20 @@ int main() {
191191
where `std::max_align_t` requires the same alignment for each scalar type, so it has almost no difference in maximum scalars.
192192
In turn, the result on most platforms is `long double`, so the alignment requirement for `AlignasStorage` we get here is 8 or 16.
193193
194+
### Dynamic allocation of over-aligned types
195+
196+
Before C++17, a `new` expression could not guarantee the alignment requirement of an **over-aligned** type (one whose alignment exceeds `alignof(std::max_align_t)`); using such types often required platform-specific facilities such as `posix_memalign` or `_aligned_malloc`. C++17 introduced `operator new` / `operator delete` overloads taking a `std::align_val_t`, so a `new` expression automatically selects the aligned version when allocating an over-aligned type:
197+
198+
```cpp
199+
struct alignas(64) Aligned {
200+
double v[8];
201+
};
202+
203+
Aligned* p = new Aligned; // C++17: automatically uses the aligned operator new
204+
// now reinterpret_cast<std::uintptr_t>(p) % 64 == 0
205+
delete p;
206+
```
207+
194208
## Conclusion
195209

196210
Several of the features introduced in this section are those that

‎book/zh-cn/09-others.md‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,20 @@ int main() {
179179
其中 `std::max_align_t` 要求每个标量类型的对齐方式严格一样,因此它几乎是最大标量没有差异,
180180
进而大部分平台上得到的结果为 `long double`,因此我们这里得到的 `AlignasStorage` 的对齐要求是 8 或 16。
181181
182+
### 过对齐类型的动态分配
183+
184+
在 C++17 之前,`new` 表达式无法保证满足**过对齐 (over-aligned)** 类型(即对齐要求超过 `alignof(std::max_align_t)` 的类型)的对齐需求,使用这类类型常常需要借助平台特定的 `posix_memalign`、`_aligned_malloc` 等手段。C++17 引入了接受 `std::align_val_t` 参数的 `operator new` / `operator delete` 重载,使得 `new` 表达式在为过对齐类型分配内存时会自动选用对齐版本:
185+
186+
```cpp
187+
struct alignas(64) Aligned {
188+
double v[8];
189+
};
190+
191+
Aligned* p = new Aligned; // C++17:自动使用对齐版本的 operator new
192+
// 此时 reinterpret_cast<std::uintptr_t>(p) % 64 == 0
193+
delete p;
194+
```
195+
182196
## 总结
183197

184198
本节介绍的几个特性是从仍未介绍的现代 C++ 新特性里使用频次较靠前的特性了,`noexcept` 是最为重要的特性,它的一个功能在于能够阻止异常的扩散传播,有效的让编译器最大限度的优化我们的代码。

‎code/9/9.4.aligned.new.cpp‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//
2+
// 9.4.aligned.new.cpp
3+
// chapter 09 others
4+
// modern c++ tutorial
5+
//
6+
// created by changkun at changkun.de
7+
// https://github.com/changkun/modern-cpp-tutorial
8+
//
9+
10+
#include <cstdint>
11+
#include <iostream>
12+
#include <new>
13+
14+
// Over-aligned type: its alignment exceeds the default new alignment.
15+
struct alignas(64) Aligned {
16+
double v[8];
17+
};
18+
19+
int main() {
20+
// C++17: new automatically uses the aligned operator new for
21+
// over-aligned types, so the result respects alignof(Aligned).
22+
Aligned* p = new Aligned;
23+
std::cout << "alignof = " << alignof(Aligned) << "\n";
24+
std::cout << "aligned? = "
25+
<< (reinterpret_cast<std::uintptr_t>(p) % alignof(Aligned) == 0)
26+
<< "\n";
27+
delete p;
28+
}

0 commit comments

Comments
 (0)