题 在catch区外面“抛出”是什么?


我只是偶然发现了这段代码:

void somefunction()
{
   throw;
}

我想知道:这是什么意思?


我将问题标记为C ++和Visual C ++,因为我不知道答案。答案可能与标准或特殊的Visual C ++扩展或忽略标准的Visual C ++有关。这就是为什么我认为这两个标签都是合理的。


19
2018-04-22 15:16


起源


此问题与Visual Studio或任何类型的“可视化”c ++无关。请不要使用具体的框架标签标记通用C ++问题。 - P Shved
@Pavel Shved:如果有某种语言扩展适用,问题可能与VC ++有关。在这种情况下,最好在此基础上回答,同时根据标准指出答案。 - David Thornley
@David,@ Tobias,我认为如果你不确定,最好不要将问题标记为VC相关。如果它恰好是语言扩展,社区将适当地重新标记它。 - P Shved
@Pavel:我觉得如果提问者不确定,我宁愿把它标记为与VC ++相关。这肯定是有争议的。在任何情况下,托比亚斯,请确保在重要时指定平台,尽管现在确实存在分歧的问题。 - David Thornley
可能重复 抛出会发生什么;语句是在catch块之外执行的吗? - anton_rh


答案:


当然,有可能 somefunction() 只是从某些内部召唤过 catch 阻止(猜测,这可能是意图)。

如果 throw; 当异常未激活时执行,它会调用 terminate() (第15.1节/ 8)。


29
2018-04-22 15:21





它重新抛出当前活动的异常。从catch-block中调用它(可能是间接的)是有意义的。这个:

#include <iostream>
using namespace std;

void f() {
    throw;
}

int main() {
    try {
        try {
            throw "foo";
        }
        catch( ... ) {
            f();
        }
    }
    catch( const char * s ) {
        cout << s << endl;
    }
}

打印“foo”。


9
2018-04-22 15:18





对于 throw 作为“外部”或“内部”catch块的概念是在运行时术语中定义的,而不是在您似乎假设的编译时术语中定义的。所以,如果在运行期间那样 throw 在a的运行时上下文中执行 catch 然后阻止 throw 按预期工作。除此以外, terminate() 叫做。

实际上,如果你仔细研究一下如何在语言规范中定义C ++异常,那么很多关于它们的东西都是在运行时术语中定义的。有时它甚至看起来像是非C ++。


5
2018-04-22 16:09



不,我没有假设这样的事情。但我没有充分评论该功能的用法。很抱歉对于这个误会。 - Tobias Langner


人们已经解释了它的含义,但知道你为什么会看到它可能是有用的。这是构建“通用”异常处理程序的有用方法,该异常处理程序根据类型处理异常,以减少重复代码的数量。

所以,如果我们采取 尼尔的例子 并扩展什么 f() 可能正在做的事情我们最终会得到一个类似于我的实现 LogKnownException() 我提出的功能 这个答案

如果您正在一个团队中工作,他们喜欢在所有地方记录所有异常情况,那么在所有这些地方(或者更糟糕的是宏)上有大量的catch块集合,你可以拥有一个看起来很简单的catch块喜欢这个

catch(...)
{
   LogKnownException();
}  

虽然我希望我改变我之前的例子 LogKnownException() 一个只是允许它不想记录的异常传播出来并继续以未处理的方式。

我并不是说这必然是一件好事,只是指出这是你可能会看到使用的结构的地方。


3
2018-04-22 17:09