异常概述
- 语法错误:程序书写不符合语法规则,编译程序发现
- 逻辑错误:程序设计不当造成程序没有完成预期的功能,静态分析和同态测试发现
- 运行异常:程序设计对程序运行环境考虑不周而造成的程序运行错误
- 异常处理
- 就地处理
- abort: 立即终止程序的执行,不作任何的善后处理工作
- exit: 关闭被程序打开的文件、调用全局对象和 static 存储类的局部对象的析构函数(不要在这些对象类的析构函数中调用 exit)
- 异地处理
- 通过函数的返回值,或指针/引用类型的参数,或全局变量把异常情况通知函数的调用者,由调用者处理
- 通过语言提供的结构化异常处理机制进行处理
- 就地处理
C++ 异常处理机制
try {
<语句序列>;
throw <表达式>;
}
catch (<类型> [<变量>]){
<语句序列>
}
- 一个 try 语句块的后面可以跟多个 catch 语句块,用于捕获不同类型的异常对象并进行处理
- try 语句块 throw 了异常对象,如果该 try 语句块之后
- 有能够捕获该异常对象的 catch 语句,则执行这个 catch 语句中的<语句序列>,然后继续执行这个 catch 语句之后的非 catch 语句
- 没有能够捕获该异常对象的 catch 语句,则由函数调用链上的上一层函数中的 try 语句的相应 catch 来捕获
- try 语句嵌套
- 当在内层的 try 语句的执行中产生了异常,则首先在内层 try 语句块之后的 catch 语句序列中查找与之匹配的处理,如果内层不存在能捕获相应异常的 catch,则逐步向外层进行查找
- 如果抛掷的异常对象在程序的调用链上没有给出捕获,则调用系统的 terminate 函数进行标准的异常处理。默认情况下,terminate 函数将会去调用 abort 函数
- 异常处理实现机制
- 每个函数拥有一个 catch 表
- 每进入一个 try,都会把其后的所有 catch 入口地址记录在相应函数的 catch 表中
- 执行 throw 时,顺着调用链去搜索 catch 入口,并进行栈的处理
- 系统的异常处理为 terminate
程序调试
- assertion
- 宏 assert: 在宏名 NDEBUG 没有定义时才有效
- assert.h
- cassert