gpt4 book ai didi

c++ - 在展开过程中抛出——为什么这个例子有效?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:05:10 24 4
gpt4 key购买 nike

考虑一下:

void thrower () {
throw "123";
}

struct Catcher {
~ Catcher () {
try {thrower ();}
catch (...) {}
}
};

int main () {
try {
Catcher c;
throw 1.23;
}
catch (...) {}
}

在 gcc 4.3 上不调用 terminate 就可以编译和运行,但是 according to the standard (15.5.1)

...when the exception handling mechanism, after completing evaluation of the expression to be thrown but before the exception is caught (15.1), calls a user function that exits via an uncaught exception... terminate shall be called.

~Catcher 在 double 被抛出后被调用时,这是“在完成评估之后......在异常被捕获之前”并且 thrower 是“一个用户通过未捕获的异常退出的函数”,这满足上述条件。是的,char* 被捕获,但仅在用户函数退出 之后。

不应该调用 terminate 吗?

强调这一点:

void do_throw () {
throw "123";
}

void thrower () {
do_throw ();
// Uncaught exception here (A)
}

struct Catcher {
~ Catcher () {
try {thrower (); /* (B) */}
catch (...) {}
}
};

int main () {
try {
Catcher c;
throw 1.23;
}
catch (...) {}
}

(A) 发生在 (B) 的上下文中,而 (B) 已经有一个正在进行的异常。

所以,不应该调用 terminate 吗?如果不是,并且这是我们可以同时有两个异常(exception)的法律情况,我们在哪里划界线?

最佳答案

为什么要调用terminate?您有一个捕获所有异常的 catch(...) block :一个捕获 double (main 中的一个)和一个捕获 char const[4](~Catcher 中的那个)。

所以没有函数“退出时出现未捕获的异常”,因为所有的异常都被捕获了。

这里的关键词是“调用以未捕获的异常终止的用户函数”。这与“调用一个用户函数,该函数在某处调用一个以未捕获的异常终止的用户函数”相同。如果你调用一个函数并且它有一个 try/catch block ,然后你调用了一些以异常终止的函数但是你捕获了异常,terminate 没有被调用。

tl;dr:调用层次结构中的第一个调用在异常评估之间和捕获之前必须退出并调用终止异常,< em>not 分支低于第一个调用。这是有道理的,因为您无法在抛出的对象被评估和被捕获之间设置另一个 catch block 。

关于c++ - 在展开过程中抛出——为什么这个例子有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7319810/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com