异常 exccpticn
异常处理
- 断言/if-else
assert()
中断程序执行(直接中断不给修复的机会)
assert 报错只有程序能看懂的信息(数据结构的)对用户不是很友好
错误码
sgrt(1) >= 0
异常(C++)
try catch {} 在栈上寻找代码-> raise/throvo
c++异常
C++ 提供的异常类
1 2
| #include <stdexcept> #include <exception>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
#include <iostream> using namespace std;
int main() {
try { cout << "throwing" << endl; throw(1); cout << "lalalala" << endl;
} catch (int &e) { cout << "caught an integer" << endl; } catch(...) { cout << "exception caught" << endl; }
return 0; }
|

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| #include <iostream> using namespace std;
class MyException : public runtime_error {
public : MyException(const string &s) : runtime_error(s) { cout << "MyException ctor" << endl; } const char *what() const noexcept override { return "123"; } };
int main() {
try { cout << "throwing" << endl; throw(MyException("hello world")); cout << "lalalala" << endl;
} catch (runtime_error &e) { cout << e.what() << endl; } catch(...) { cout << "exception caught" << endl; }
return 0; }
|
栈堆-异常

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
|
#include <iostream> using namespace std;
#define BEGINS(x) namespace x { #define ENDS(x) }
BEGINS(test1)
class MyException : public runtime_error {
public : MyException(const string &s) : runtime_error(s) { cout << "MyException ctor" << endl; } const char *what() const noexcept override { return "123"; } };
int main() {
try { cout << "throwing" << endl; throw(MyException("hello world")); cout << "lalalala" << endl;
} catch (runtime_error &e) { cout << e.what() << endl; } catch(...) { cout << "exception caught" << endl; }
return 0; }
ENDS(test1)
BEGINS(test2)
class Helper {
public :
Helper() { cout << this << " : Helper ctor" << endl; }
~Helper() { cout << "Helper dtor" << endl; }
void boom() { cout << "boom" << endl; }
};
void inner() {
Helper p1[3]; Helper *p2 = new Helper[3];
throw(1); p1[0].boom(); }
void outer() { try { inner(); } catch(...) { cout << "exception caught" << endl; } }
int main() { outer();
return 0; }
ENDS(test2)
int main() {
test2::main();
return 0; }
|
函数调用过程
处理函数参数
一般来所 (压栈)实现
将返回地址
压栈
备份原栈帧
压栈
开辟信栈帧
4种函数调用方式
- codecl (c++/c默认)
- stdcall
- fastcall
- 类(thiscall)
codecl
放参数(栈)、调用函数、清理参数
特点:参数放在栈上、参数由外层清理
汇编流程
向栈上反向push参数
call调用(自动push返回地址)
push ebp (备份原栈底)
mov ebp, eso (提高栈底)
sub esp, _ (提高栈顶)
add esp, _ (恢复栈顶)
mov esp, ebp (恢复栈顶)
pop ebp (恢复栈底)
ret 清返回地址并返回
在函数外清理参数

