异常离开尚未完成的作用域
函数无法在当前位置处理异常时,控制流可能向外寻找匹配处理程序。栈展开描述这段传播中相关调用与作用域怎样退出,以及需要执行哪些局部清理。
C++标准草案规定,传播到处理程序时,应析构已经完成构造且尚未析构的相关自动存储期对象,顺序与构造完成次序相反。它不是简单丢弃一段栈内存而忽略对象规则。
参考:[1]
部分构造也有清理规则
若构造一个对象的过程中抛出异常,某些成员或基类子对象可能已经完成构造。C++会按规定清理这些已完成的部分,而不能假定整个最外层对象早已建立完毕。
把资源交给具有正确析构行为的成员,可使这套规则自动释放已取得的资源。只把原始句柄放进普通变量,却没有相应所有权封装,则不会仅凭栈展开自动发明正确释放动作。
清理与业务回滚分开
释放锁或关闭本地资源,并不会自动收回已经发出的通知、恢复远端修改,或把多项业务操作变成事务。栈展开保障的是相应语言和对象规则,不是任意外部世界的逆执行。
终止或中止路径还可能采用不同于正常异常传播的规则。设计接口时应说明错误是否向上展开、哪些资源由对象负责,以及怎样报告清理之外的失败;不能仅凭出现catch就认定所有收尾已经完整。