【发布时间】:2010-12-29 23:45:14
【问题描述】:
一般来说,在抛出并捕获异常后,程序在哪里恢复执行?它是在抛出异常的代码行之后继续,还是在捕获异常的地方继续?此外,这种行为在大多数编程语言中是否一致?
【问题讨论】:
-
你问的是 Python 还是 C++ - 两者也不是很相似。
一般来说,在抛出并捕获异常后,程序在哪里恢复执行?它是在抛出异常的代码行之后继续,还是在捕获异常的地方继续?此外,这种行为在大多数编程语言中是否一致?
【问题讨论】:
catch块内的代码被执行,原来的执行在catch块之后继续。
在捕获到异常的地方继续执行,即在catch 块的开头,该块专门针对当前异常类型。执行 catch 块,忽略其他 catch 块(将多个 catch 块视为 switch 语句)。在某些语言中,finally 块也可以在catch 之后执行。然后程序继续执行整个try ... catch ... finally ...之后的下一条指令。
你应该注意,如果一个异常没有在一个块中被捕获,异常会被传播到当前函数的调用者,并向上调用堆栈直到catch处理这个异常。在这种情况下,您可以将函数调用想象成一个宏:在调用它的位置插入每个函数的代码,您将清楚地看到每个 try .. catch ... finally ... 块的嵌套。
如果没有异常处理程序,程序通常会崩溃。 (在这一点上,某些语言可能会有所不同)。
执行流的行为在我所知道的每种语言中都是一致的。唯一的区别在于try ... catch ... finally ... 构造:finally 并不存在于每种语言中,某些语言不允许finally 和catch 在同一块中(您必须嵌套两个try 到使用 2),某些语言允许捕获所有内容(C++ 中的 catch (...)),而某些语言则不允许。
【讨论】:
在 catch 块中继续执行(捕获异常的地方)。
这在使用异常的语言中是一致的。
需要注意的重点(尤其是在 C++ 中)
在 throw 和 catch 点之间,堆栈以有序的方式展开,以便在堆栈上创建的所有对象都被正确销毁(以预期的顺序)。这导致了称为 RAII 的技术。
【讨论】:
我手边没有 Bjarne Stroustrup 的“设计与进化”副本,但我相信他在那里写了一些关于可恢复异常的经验。他们发现他们使事情变得更难纠正。毕竟,如果某行发生意外错误,您的异常处理程序必须对问题进行充分修补,以允许在不知道上下文的情况下继续执行。这可能是内存不足的错误(尽管此类错误通常是内存分配失控的结果,并且添加更多内存并不能真正解决任何问题),但一般情况下不会。
因此,在 C++ 和我熟悉的所有语言中,使用 catch 继续执行,并且不会自动返回引发异常的地方。
【讨论】:
它在异常被捕获的地方恢复。否则,写例外条款的意义何在?
【讨论】:
throw [[returnable]] Type(); 一样发出信号。否则我想这可能会导致一团糟。