Skip to content

Commit a133f8f

Browse files
committed
add tl expected error
1 parent 427b4b1 commit a133f8f

File tree

5 files changed

+2560
-5
lines changed

5 files changed

+2560
-5
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cmake_minimum_required(VERSION 3.12)
22

3-
set(CMAKE_CXX_STANDARD 20)
3+
set(CMAKE_CXX_STANDARD 23)
44

55
project(main)
66

docs/img/llvm-basic-block-branch.png

57.7 KB
Loading

docs/llvm_intro.md

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,12 @@ Clang 只是 LLVM 项目中的一个前端,其负责编译 C/C++ 这类语言
2727
- LLVM 官方仓库:https://github.com/llvm/llvm-project
2828
- LLVM 用户文档:https://llvm.org/docs/
2929
- LLVM 源码级文档:https://llvm.org/doxygen/
30-
- 《Learn LLVM 17》:https://github.com/xiaoweiChen/Learn-LLVM-17
3130
- LLVM IR 全文档:https://llvm.org/docs/LangRef.html
31+
- 《Learn LLVM 17》:https://github.com/xiaoweiChen/Learn-LLVM-17
3232
- 《开始学习 LLVM》:https://getting-started-with-llvm-core-libraries-zh-cn.readthedocs.io/zh-cn/latest/
3333
- 《miniSysY 编译实验》:https://buaa-se-compiling.github.io/miniSysY-tutorial/pre/llvm.html
34-
- A Gentle Introduction to LLVM IR:https://mcyoung.xyz/2023/08/01/llvm-ir/
34+
- 《A Gentle Introduction to LLVM IR》:https://mcyoung.xyz/2023/08/01/llvm-ir/
35+
- 《LLVM IR C++ API Tutorial》:https://mukulrathi.com/create-your-own-programming-language/llvm-ir-cpp-api-tutorial/
3536

3637
> {{ icon.warn }} 不建议按顺序全部逐个阅读完,这么多文档小彭老师都看不完。建议遇到了不熟悉的指令时,再去针对性地找到相应章节,学习。
3738
@@ -1180,15 +1181,16 @@ define dso_local noundef i32 @main() #0 {
11801181

11811182
> {{ icon.story }} 如果直接 `ret i32 @i` 的话,就变成 `return &i` 的效果了。
11821183
1183-
#### 调用其他函数
1184+
#### `call` 调用其他函数
11841185

11851186
```llvm
11861187
define dso_local noundef i32 @main() #0 {
11871188
%1 = call i32 (ptr, ...) @printf(ptr noundef @.str)
11881189
ret i32 0
11891190
}
11901191
```
1191-
todo
1192+
1193+
TODO
11921194

11931195
### 轶事:LLVM IR 不跨平台
11941196

@@ -1429,6 +1431,14 @@ attributes #0 = { mustprogress noinline norecurse nounwind optnone sspstrong uwt
14291431
!5 = !{!"clang version 18.1.8"}
14301432
```
14311433

1434+
现在,我们用 `opt` 工具对其进行优化:
1435+
1436+
TODO
1437+
1438+
## 基本块与分支
1439+
1440+
![](img/llvm-basic-block-branch.png)
1441+
14321442
## 汇编语言(ASM)
14331443

14341444
## 汇编语言的终局:机器码

examples/error_code.cpp

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#include <fmt/core.h>
2+
#include <system_error>
3+
#include "tl-expected.hpp"
4+
// 今日主题:现代 C++ 中的错误处理
5+
6+
// int : [INT_MIN, INT_MAX]
7+
// optional<int> : [INT_MIN, INT_MAX] | {nullopt}
8+
// variant<int, error_code> : [INT_MIN, INT_MAX] | {error_code}
9+
// expected<int, error_code> : [INT_MIN, INT_MAX] | {error_code}
10+
11+
namespace mybuss {
12+
13+
enum class login_errc {
14+
success = 0,
15+
not_valid_pass,
16+
not_login,
17+
};
18+
19+
auto const &login_category() {
20+
static const struct : std::error_category {
21+
virtual std::string message(int val) const override {
22+
switch ((login_errc)val) {
23+
case login_errc::success:
24+
return "登录成功!";
25+
case login_errc::not_valid_pass:
26+
return "密码不正确!";
27+
case login_errc::not_login:
28+
return "用户未登录!";
29+
default:
30+
return "未知错误!";
31+
};
32+
}
33+
34+
virtual const char *name() const noexcept override {
35+
return "login";
36+
}
37+
} instance;
38+
return instance;
39+
}
40+
41+
std::error_code make_error_code(login_errc ec) {
42+
return std::error_code((int)ec, login_category());
43+
}
44+
45+
}
46+
47+
tl::expected<int, std::error_code> sqrt(int x) {
48+
// 假装这是一个关于网站登录的业务函数
49+
if (x < 0) {
50+
return tl::unexpected{make_error_code(std::errc::argument_out_of_domain)};
51+
}
52+
if (x == 3) {
53+
return tl::unexpected{make_error_code(mybuss::login_errc::not_valid_pass)};
54+
}
55+
if (x == 4) {
56+
return tl::unexpected{make_error_code(mybuss::login_errc::not_login)};
57+
}
58+
for (int i = 0;; i++) {
59+
if (i * i >= x) {
60+
return i;
61+
}
62+
}
63+
}
64+
65+
tl::expected<int, std::error_code> sqrfloor(int x) {
66+
if (x < 1) {
67+
return tl::unexpected{make_error_code(std::errc::invalid_argument)};
68+
}
69+
auto ret = sqrt(x * x);
70+
return ret.map([&] (int x) { fmt::println("x * 2"); return x * 2; });
71+
// 等价于:
72+
// if (!ret.has_value()) {
73+
// return tl::unexpected{ret.error()};
74+
// }
75+
// x = ret.value();
76+
// x *= 2;
77+
// return x;
78+
79+
// return ret.map_error([&] (std::error_code ec) {
80+
// if (ec == make_error_code(mybuss::login_errc::not_login)) {
81+
// ec = make_error_code(mybuss::login_errc::not_valid_pass);
82+
// }
83+
// return ec;
84+
// });
85+
// 等价于:
86+
// if (!ret.has_value()) {
87+
// if (ret.error() == make_error_code(mybuss::login_errc::not_login)) {
88+
// ret.error() = make_error_code(mybuss::login_errc::not_valid_pass);
89+
// }
90+
// }
91+
}
92+
93+
int main() {
94+
auto ret = sqrfloor(3);
95+
if (ret.has_value()) {
96+
fmt::println("结果: {}", ret.value());
97+
} else {
98+
fmt::println("出错: {}", ret.error().message());
99+
}
100+
return 0;
101+
}

0 commit comments

Comments
 (0)