Exception Handling
C 错误处理机制
-
终止程序:如
assert
。 -
返回错误码:需要自己找错误出在哪里,而且很多系统接口都会把错误码放到
errno
中。
实际中 C 程序都是使用错误码的方式处理错误,部分情况下使用终止程序处理严重的错误。
C++ 异常处理机制
当一个函数出现自己无法处理的错误时就可以抛出异常,让函数的直接或间接调用者处理这个问题。
发生异常时必须将异常明确地抛出,try才能检测到;如果不抛出来,即使有异常try也检测不到。异常一旦抛出,会立刻被try检测到,并且不会再执行异常点(异常发生位置)后面的语句。意思就是:检测到异常后程序的执行流会发生跳转,从异常点跳转到catch所在的位置,位于异常点之后的、并且在当前try块内的语句就都不会再执行;即使catch语句成功地处理了错误,程序的执行流也不会再回退到异常点,所以这些语句永远都没有执行的机会。执行完 catch 块所包含的代码后,程序会继续执行 catch 块后面的代码。
因为异常会导致执行流跳转,程序中应尽量避免使用异常,频繁的异常抛出很容易引起不必要的错误。对于正常的返回值,或者不太严重、可以重试 / 恢复的错误,建议不使用异常,把它们归到正常的流程里。
几个使用异常的判断准则:
-
不允许被忽略的错误;
-
极少数情况下才会发生的错误;
-
严重影响正常流程,很难恢复到正常状态的错误;
-
无法本地处理,必须“穿透”调用栈,传递到上层才能被处理的错误。
noexcept
C++ 11提出了一个新的编译阶段命令:noexcept
, 被它修饰的函数,就是告诉编译器这个函数不会抛出异常,允许编译器对该函数进行优化,不去加那些栈展开的额外代码,消除异常处理的成本。但承诺只是承诺,被修饰的函数如果真的抛出也不会报错。