8.1.5 异常和效率
2025年09月26日
8.1.5 异常和效率
在没有抛出异常之前,异常处理的实现在运行时没有产生任何额外开销。抛出异常并不比调用函数的开销大。在完成这些的同时,要维持与C语言在调用序列、排错规范等方面的兼容性,而又不引起显著的额外存储开销,这是非常困难的。简单使用那些能代替异常的东西是需要代价的。在多数的大规模程序中或系统软件中,更多的代码(甚至超过一半)实际上是用于错误处理和异常处理的。对于下述形式的代码:
如果g()函数会抛出异常,那么f()函数必须包含部分代码,使异常发生时能够得到即时处理。例如,确保字符串变量s被正确销毁。如果g()函数不采用抛出异常的方式,也会得到使用另一种方式报告发生的错误。与之相较,使用常规方式写出的处理错误的代码需要包含大量的if判断和return语句。就像排雷一样,走一步就要判断一步。
异常描述可能非常有助于改进所生成的代码。但是,传统的C函数不会抛出异常的。大部分程序中,每个C函数均可用“空抛出”描述throw()声明,即
上述函数定义中throw()的参数表为空,说明此函数不能抛出任何异常。对于标准C库函数只有很少的几个函数可以抛出异常,例如atexit()和qsort()。
atexit()函数指定func()函数在程序终止时被调用。如果调用成功,函数返回0;如果调用失败,函数返回非零。进程函数func()必须返回void,并且不允许包含参数。
qsort()函数在前面讲述算法的章节已有介绍。
利用这些函数可以生成更优质的代码。值得注意的是,在为某个C函数空异常描述throw()之前,要思考一下该函数是否有必要抛出异常。