在抛出旧异常时抛出新异常

fre*_*low 5 c++ java exception-handling

如果析构函数在由异常引起的堆栈展开期间抛出C++,程序将终止.(这就是析构函数永远不应该使用C++的原因.)示例:

struct Foo
{
    ~Foo()
    {
        throw 2;   // whoops, already throwing 1 at this point, let's terminate!
    }
};

int main()
{
    Foo foo;
    throw 1;
}

terminate called after throwing an instance of 'int'

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Run Code Online (Sandbox Code Playgroud)

如果由于相应的try块中的异常而在Java中输入finally块,并且finally块抛出第二个异常,则会以静默方式吞下第一个异​​常.例:

public static void foo() throws Exception
{
    try
    {
        throw new Exception("first");
    }
    finally
    {
        throw new Exception("second");
    }
}

public static void main(String[] args)
{
    try
    {
        foo();
    }
    catch (Exception e)
    {
        System.out.println(e.getMessage());   // prints "second"
    }
}
Run Code Online (Sandbox Code Playgroud)

这个问题在我脑海中浮现:编程语言是否可以处理同时抛出的多个异常?这会有用吗?你有没有错过这种能力?有没有一种语言可以支持这个?有这种方法的经验吗?

有什么想法吗?

Pot*_*ter 5

考虑流量控制.例外基本上只是花哨setjmp/ longjmpsetcc/ callcc无论如何.异常对象用于选择要跳转到的特定位置,如地址.异常处理程序只是递归当前异常,longjmp直到它被处理.

一次处理两个异常只是将它们捆绑在一起,这样结果就可以产生一致的流量控制.我可以想到两个选择:

  • 将它们组合成一个无法捕获的异常.这相当于展开整个堆栈并忽略所有处理程序.这会产生异常级联导致完全随机行为的风险.
  • 以某种方式构建他们的笛卡尔积.是的,对.

C++方法很好地满足了可预测性的需要.