C++ 标准说([except.handle]/9):
如果找不到匹配的处理程序,则调用函数std :: terminate(); 在对std :: terminate()的调用是否为实现定义之前,是否展开堆栈
例如,下面的代码行为(是否打印S::~S())是实现定义的:
struct S {
S() { std::cout << "S::S()" << std::endl; }
~S() { std::cout << "S::~S()" << std::endl; }
};
int main() {
S s;
throw std::runtime_error("exception");
}
Run Code Online (Sandbox Code Playgroud)
我想深入了解:为什么要定义实现?std::terminate()如果异常未被捕获(与try{ ... } catch(...) { throw; }顶级函数类似),为什么在调用异常之前,为什么上下文不能被取消?一目了然,这种行为与RAII的一致性更加清晰和安全.
Sto*_*ica 11
如果未捕获异常,std::terminate则调用.我们失败了,主机环境需要介入并且(可能)在我们之后进行清理.在这种情况下解开堆栈就像给一个神风飞行员一个头盔.
因此,对于托管环境,只做任何事情并让主机清理可能更有意义.
现在,如果你处于一个独立的实现中,并且抛出异常,那么就没有人可以在你之后进行清理.在这种情况下,实现应该预先形成堆栈展开,因为这是应该清理混乱的东西.
该标准将其留给实现以促进这两个非常不同的执行环境.
就像@Matteo指出的那样,std::terminate在任何潜在的展开之前调用,因为你可以为它设置一个处理程序.并且该处理程序可以对堆栈状态执行一些有用的操作,只要堆栈尚未解开.
| 归档时间: |
|
| 查看次数: |
531 次 |
| 最近记录: |