Exception handling 发生两个异常时会发生什么?

Exception handling 发生两个异常时会发生什么?,exception-handling,Exception Handling,当程序有两个异常时,程序将如何运行。 而且他们都还没有被抓到。 将调用什么类型的处理程序。 假设这两个例外都是不同类型的。 如果我不清楚,我道歉,但我觉得我已经说得够清楚了。 谢谢你 如果try块抛出一个异常,try块退出会破坏所有的自动变量。假设其中一个是自动对象,它的析构函数再次抛出一个异常。现在我们有两个未捕获的异常。我的问题基于这个事实。 谢谢 这完全取决于语言。然而,在我所知道的所有语言中,不可能同时存在多个异常(在同一线程中)。如果抛出了异常,它将沿着调用堆栈向上移动,直到被捕获为止

当程序有两个异常时,程序将如何运行。 而且他们都还没有被抓到。 将调用什么类型的处理程序。 假设这两个例外都是不同类型的。 如果我不清楚,我道歉,但我觉得我已经说得够清楚了。 谢谢你


如果try块抛出一个异常,try块退出会破坏所有的自动变量。假设其中一个是自动对象,它的析构函数再次抛出一个异常。现在我们有两个未捕获的异常。我的问题基于这个事实。
谢谢

这完全取决于语言。然而,在我所知道的所有语言中,不可能同时存在多个异常(在同一线程中)。如果抛出了异常,它将沿着调用堆栈向上移动,直到被捕获为止,在此期间不会执行任何代码。如果未捕获异常,则程序会在抛出另一个异常之前崩溃。如果捕获到异常,则异常不再“活动”,如果处理程序抛出新异常,则旧异常将被遗忘。

在CPU级别(x86上),存在一种称为:

在x86体系结构上,如果处理器在尝试处理挂起的中断或异常时遇到问题,则会发生双故障异常


然而,这种“双重故障”是一种非常低级的情况,只与操作系统内核有关。

当发生异常时,编译器将展开堆栈(关闭当前函数并返回调用函数)。若主编译器中未捕获异常,则调用abort函数。由该程序异常终止

但在展开堆栈的过程中,若发生了另一个异常(对于析构函数中的情况),则此时/点未到达主函数,编译器将调用异常终止程序的中止函数

若您知道在析构函数中可能发生异常,那个么必须在析构函数中处理异常。这意味着在析构函数中,您应该有catch块来捕获该异常。通过这种方式,生成的第二个异常将在析构函数中处理,并且该异常不会从析构函数中传出,并且程序将从崩溃中保存,因为一次生成两个异常


编译器一次只处理一个异常。如果编译器发现多个异常调用中止函数,程序将通过该函数异常终止。

很少有语言或框架能够很好地处理在清除早期异常时发生的异常。有效地处理这种情况需要清理代码知道“主线”上发生了什么异常(如果有)。从概念上讲,将此类信息提供给清理代码并不困难,但框架通常不提供


另外,C++中的正常行为是在另一个异常清理过程中发生异常时,系统会硬崩溃;如果发生清理异常,Java和.NET语言通常会放弃任何挂起的异常。然而,较新版本的Java包含一个特性(如果使用的话)可以更好地处理这些事情。在try-with-resources块中,当没有其他异常挂起时,在清理资源时发生的异常将被正常处理;但是,如果异常处于挂起状态,则挂起的异常将保持挂起状态,但会将新异常添加到其“抑制的异常”列表中。如果有一种方法可以指定一个特定的

finally
块的行为应该是相同的,那就太好了,但是我不知道有什么特性可以做到这一点。

请准确地解释操作系统和编译器发生了什么。+1以保持正常运行。对于第一次接触异常处理的人来说,这可能不是一个罕见的问题。这条线索很好地澄清了困惑。你能解释一下你的问题吗?如果异常来自操作系统,为什么您会在意,因为操作系统将处理它。如果它来自编译器,则取决于编译器(但通常只能引发一个异常)如果try块抛出一个异常,try块退出会破坏所有的自动变量。假设其中一个是自动对象,它的析构函数再次抛出一个异常。现在我们有两个未捕获的异常。我的问题基于这个事实。非常感谢。同样,这取决于语言。在C++中,标准行为是如果在堆栈展开过程中抛出异常,则崩溃程序(参见)。在爪哇中,异常可以从catch块或最终块中抛出。