Skip to content

Commit 86a1ac5

Browse files
fix ci check
1 parent 9421c3e commit 86a1ac5

6 files changed

Lines changed: 38 additions & 38 deletions

File tree

documents/vol10-open-lecture-notes/cppcon/2025/01-concept-based-generic-programming/01-type-safety-and-number-concept.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ int main() {
321321

322322
跑一下看看输出:
323323

324-
```
324+
```text
325325
捕获到: narrowing conversion detected
326326
捕获到: narrowing conversion detected
327327
捕获到: narrowing conversion detected
@@ -386,7 +386,7 @@ int main() {
386386

387387
输出:
388388

389-
```
389+
```text
390390
x = 42, y = 3, z = 100
391391
sum = 142
392392
捕获到: narrowing conversion detected
@@ -780,7 +780,7 @@ int main() {
780780

781781
跑起来输出是这样的:
782782

783-
```
783+
```text
784784
3
785785
捕获到异常: 下标越界了兄弟
786786
```
@@ -845,7 +845,7 @@ int main() {
845845

846846
输出:
847847

848-
```
848+
```text
849849
捕获到异常: 负数下标,你想干嘛
850850
```
851851

@@ -904,7 +904,7 @@ int main() {
904904

905905
输出:
906906

907-
```
907+
```text
908908
前 3 个元素的和: 6
909909
捕获到异常: params[0] 不是合法的正整数
910910
```
@@ -1045,7 +1045,7 @@ int main() {
10451045

10461046
输出:
10471047

1048-
```
1048+
```text
10491049
前3个: 10 20 30
10501050
中间3个: 30 40 50
10511051
捕获: take_front: n 超过了 span 的大小

documents/vol10-open-lecture-notes/cppcon/2025/01-concept-based-generic-programming/03-syntax-advanced-concepts-and-generic-philosophy.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ void test_std_pair_narrowing() {
108108

109109
## 自己写一个安全的 pair:NonNarrowConvertible
110110

111-
我们在 [第一篇](01-narrowing-and-type-safety) 中已经深入讨论了窄化转换的检测机制,这里我们用一个更简洁的方式——利用花括号初始化禁止窄化的语言规则——来实现 `NonNarrowConvertible`。思路很简单:在拷贝构造的时候,用 concept 约束转换过程,不允许 narrowing。
111+
我们在 [第一篇](01-type-safety-and-number-concept.md) 中已经深入讨论了窄化转换的检测机制,这里我们用一个更简洁的方式——利用花括号初始化禁止窄化的语言规则——来实现 `NonNarrowConvertible`。思路很简单:在拷贝构造的时候,用 concept 约束转换过程,不允许 narrowing。
112112

113113
```cpp
114114
#include <iostream>
@@ -234,7 +234,7 @@ int main() {
234234

235235
我跑出来的输出大概是这样的(具体偏移可能因平台和编译选项有对齐差异):
236236

237-
```
237+
```text
238238
成员: id 偏移: 0 字节 大小: 4 字节
239239
成员: x 偏移: 4 字节 大小: 4 字节
240240
成员: y 偏移: 8 字节 大小: 4 字节
@@ -626,7 +626,7 @@ int main() {
626626

627627
跑一下输出:
628628

629-
```
629+
```text
630630
=== 面向对象方式 ===
631631
OOP: 绘制圆形
632632
OOP: 绘制矩形
@@ -657,7 +657,7 @@ concept 就像是类型系统的"合同",一旦签了就不能改,所以必
657657

658658
## 从零开始写一个 Number concept
659659

660-
关于 `Number<T>` 的完整实现和深入讨论,请参阅 [第一篇](01-narrowing-and-type-safety)。这里我只想展示这个 concept 的核心骨架,用它来说明"迭代演进"的哲学:
660+
关于 `Number<T>` 的完整实现和深入讨论,请参阅 [第一篇](01-type-safety-and-number-concept.md)。这里我只想展示这个 concept 的核心骨架,用它来说明"迭代演进"的哲学:
661661

662662
```cpp
663663
#include <iostream>
@@ -904,7 +904,7 @@ concepts 真正的价值在于**它让泛型编程的思维方式发生了变化
904904

905905
很多人(包括演讲者最初)认为泛型函数必须能够孤立编译——也就是说,只看函数定义本身,不看调用点的上下文,就应该能完成类型检查。但后来认识到这既不是我们真正需要的,也不是 concepts 所提供的。
906906

907-
我之前也有这个误区。我觉得一个好的泛型函数应该"自包含",自己就能证明自己对类型的要求是合理的。但仔细想想,这其实是一种过度要求。泛型函数的约束应该描述"我需要什么",而不是"我能处理一切"。具体某个调用点传进来的类型是否满足,那是调用点和函数约束之间的契约验证,不需要函数自己操心。关于模板编译模型和类型检查的更深入讨论,我们在 [第四篇](04-template-compilation-and-future) 中会展开。
907+
我之前也有这个误区。我觉得一个好的泛型函数应该"自包含",自己就能证明自己对类型的要求是合理的。但仔细想想,这其实是一种过度要求。泛型函数的约束应该描述"我需要什么",而不是"我能处理一切"。具体某个调用点传进来的类型是否满足,那是调用点和函数约束之间的契约验证,不需要函数自己操心。关于模板编译模型和类型检查的更深入讨论,我们在 [第四篇](04-template-compilation-and-future.md) 中会展开。
908908

909909
`std::integral` 约束参数的那个例子就是最好的说明:函数只声明"我需要一个整数",至于你传 `int` 还是 `long`,那是你的事。函数不需要孤立地知道所有可能的整数类型。
910910

documents/vol10-open-lecture-notes/cppcon/2025/02-some-assembly-required/01-personal-journey-and-from-assembly-to-cpp.md

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -100,30 +100,30 @@ main:
100100
这里有个坑必须提醒。一开始用 `-O1` 编译,结果发现 `add` 函数的汇编就两三行,参数根本没进栈,直接在寄存器里就算完了(熟悉编译器优化的朋友估计不会感觉如何,本来就是寄存器层能操作的东西,对吧!)。这是因为 `-O1` 就已经开始做寄存器分配优化了——编译器发现没必要把参数存到栈上再读回来,直接用寄存器就算了。所以如果你也想跟着做实验,一定要用 `-O0`,不然你会看到一堆看不懂的东西。
101101

102102
```asm
103-
.file "demo.cpp"
104-
.text
105-
.globl _Z3addii
106-
.type _Z3addii, @function
103+
.file "demo.cpp"
104+
.text
105+
.globl _Z3addii
106+
.type _Z3addii, @function
107107
_Z3addii:
108108
.LFB0:
109-
.cfi_startproc
110-
leal (%rdi,%rsi), %eax
111-
ret
112-
.cfi_endproc
109+
.cfi_startproc
110+
leal (%rdi,%rsi), %eax
111+
ret
112+
.cfi_endproc
113113
.LFE0:
114-
.size _Z3addii, .-_Z3addii
115-
.globl main
116-
.type main, @function
114+
.size _Z3addii, .-_Z3addii
115+
.globl main
116+
.type main, @function
117117
main:
118118
.LFB1:
119-
.cfi_startproc
120-
movl $7, %eax
121-
ret
122-
.cfi_endproc
119+
.cfi_startproc
120+
movl $7, %eax
121+
ret
122+
.cfi_endproc
123123
.LFE1:
124-
.size main, .-main
125-
.ident "GCC: (GNU) 16.1.1 20260430"
126-
.section .note.GNU-stack,"",@progbits
124+
.size main, .-main
125+
.ident "GCC: (GNU) 16.1.1 20260430"
126+
.section .note.GNU-stack,"",@progbits
127127
```
128128

129129
另一个坑是不同平台的调用约定不一样。上面展示的是 x86-64 的 System V ABI<RefLink :id="3" preview="System V Application Binary Interface, AMD64, calling convention" />,前两个整数参数分别放在 `%edi``%esi` 里,返回值放在 `%eax` 里。如果在 Windows 上用 MSVC 编译,参数传递的方式是不一样的(用的是 `%rcx``%rdx`<RefLink :id="4" preview="Microsoft, x64 Calling Convention, RCX/RDX/R8/R9" />)。所以如果跑出来的结果不一样,先检查平台和编译器。
@@ -307,7 +307,7 @@ int main() {
307307
编译一下看汇编输出(我用的环境后面会说):
308308
309309
```bash
310-
$ g++ -O0 -S simple_call.cpp -o simple_call.s
310+
g++ -O0 -S simple_call.cpp -o simple_call.s
311311
```
312312

313313
`-O0` 是关掉所有优化,因为开了优化之后编译器会把整个东西折叠成常量,我们就看不到函数调用的过程了。打开 `simple_call.s`,你会看到类似这样的东西(我截取了关键部分,AT&T 语法):
@@ -613,7 +613,7 @@ int main() {
613613
::: details 实际验证结果(Arch Linux WSL, GCC 16.1.1, -O3 -mavx2 -mfma)
614614
在验证环境中,由于 GCC 16.1 的自动向量化能力已经非常强,标量版本被编译器自动优化到了接近手动 AVX2/FMA 的水平,实际加速比只有约 1.16x:
615615

616-
```
616+
```text
617617
scalar: 1.09 ms
618618
avx2/fma: 0.94 ms
619619
speedup: 1.16x

documents/vol10-open-lecture-notes/cppcon/2025/02-some-assembly-required/02-reading-assembly-and-registers-abi.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ x86 里有一个寄存器叫 A(Accumulator,累加器)。在 8080 甚至更
314314

315315
用一个简单的示意图来说明:
316316

317-
```
317+
```text
318318
63 31 15 7 0
319319
+--------------------------------+----------+----+----+
320320
| RAX | EAX | AX |
@@ -349,7 +349,7 @@ ABI 规定的东西很多,但从读汇编的角度来说,最关心的就一
349349

350350
以 Linux(System V AMD64 ABI)为例。前六个整数参数(包括指针)依次放在这些寄存器里:
351351

352-
```
352+
```text
353353
第 1 个参数 → RDI
354354
第 2 个参数 → RSI
355355
第 3 个参数 → RDX
@@ -368,7 +368,7 @@ ABI 规定的东西很多,但从读汇编的角度来说,最关心的就一
368368

369369
如果在 Windows 上用 MSVC,情况就不一样了。Windows x64 ABI 只给了四个寄存器来传参数:
370370

371-
```
371+
```text
372372
第 1 个参数 → RCX
373373
第 2 个参数 → RDX
374374
第 3 个参数 → R8

documents/vol10-open-lecture-notes/cppcon/2025/02-some-assembly-required/05-boost-beman-and-standardization.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ int main() {
7474

7575
运行结果:
7676

77-
```
77+
```text
7878
use_count: 1
7979
value: 42
8080
after copy, use_count: 2
@@ -121,7 +121,7 @@ int main() {
121121

122122
运行结果(GCC 16.1.1, `-std=c++20`):
123123

124-
```
124+
```text
125125
created: "/tmp/test_dir"
126126
removed: "/tmp/test_dir"
127127
```

documents/vol10-open-lecture-notes/cppcon/2025/02-some-assembly-required/07-wg21-standardization-and-assembly-philosophy.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ g++-14 -std=c++20 -fmodules-ts math_utils.cppm main.cpp -o demo
637637

638638
跑一下看看:
639639

640-
```
640+
```text
641641
5^2 = 25
642642
pi = 3.14159
643643
```
@@ -653,7 +653,7 @@ pi = 3.14159
653653
::: warning 原文错误更正
654654
原版示例使用了 `reinterpret_cast` 来判断字节序,但 `reinterpret_cast` 在 C++ 标准中**不允许出现在常量表达式求值中**[expr.const]<RefLink :id="12" preview="cppreference.com, Constant expressions" />),因此 `consteval` 函数中不能使用它。GCC 16.1.1 的实际报错信息如下:
655655

656-
```
656+
```text
657657
/tmp/test.cpp:4:12: warning: 'reinterpret_cast' is not a constant expression [-Winvalid-constexpr]
658658
4 | return reinterpret_cast<const char*>(&test)[0] == 1;
659659
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

0 commit comments

Comments
 (0)