我有这段代码:
#include <iostream>
#include <exception>
class TestException : public std::exception
{
public:
char const* what() const throw() override { return msg_.c_str(); }
protected:
std::string & message() throw() { return msg_; }
private:
std::string msg_;
};
void ThrowIt()
{
throw TestException();
}
int main()
{
ThrowIt();
}
在使用Visual Studio编译的Windows上的Release或Debug中内置运行时导致程序终止,在Linux机器上使用GCC编译时也是如此,结果是:
在抛出'TestException'实例后终止调用 what():Aborted
一旦捕获到未处理的异常,两者都会终止程序。此行为是严格针对系统的还是由标准指定的?是否存在跨平台方式,我可以将catch
未处理的每个异常重新路由到处理程序而不是仅仅终止程序?
答案 0 :(得分:0)
15.5.1 的C ++ 11标准声明:
[...]当异常处理机制找不到抛出异常[...]
std::terminate()
的处理程序时。在没有找到匹配处理程序的情况下, 它是实现定义的,无论在调用std::terminate()
之前是否展开堆栈。
因此终止是标准行为,但是否可以从这种情况中恢复是实现定义的。在任何情况下都不会重新路由异常对象。
您还可以使用typedef void (*terminate_handler)();
更改由std::terminate()
调用的处理函数(terminate_handler set_terminate(terminate_handler f) noexcept;
),并使用terminate_handler get_terminate() noexcept;
进行查看。
答案 1 :(得分:0)
在您的代码中,您有一个未捕获的异常,因为您的异常没有匹配的句柄。这种行为包含在[except.terminate]
中在某些情况下,必须放弃异常处理以获得不那么微妙的错误处理技术。 [注意:这些情况是:
[...]
- 当异常处理机制找不到抛出异常(15.3)的处理程序时,或 [...]
然后我们
在这种情况下,调用std :: terminate()(18.8.3)。在没有找到匹配处理程序的情况下, 它是实现定义的,无论是否在调用std :: terminate()之前展开堆栈。
如果你想拥有&#34;顶级&#34; catch
将处理程序中的所有异常,如果未捕获,则可以将main()
中的代码包装在try...catch
块中。未捕获的任何异常将按[except.handle]
如果在try块的处理程序中找不到匹配项,则在a中继续搜索匹配处理程序 动态地围绕同一个线程的try块。
您还可以使用std::set_terminate
std::terminate_handler
答案 2 :(得分:0)
我不确定什么标准保证,但在实践中使用 GCC、clang 和 MSVC,您可以在终止处理程序中使用 std::current_exception()
来处理异常。像这样:
#include <stdexcept>
#include <iostream>
void f()
{
try
{
std::rethrow_exception(std::current_exception());
}
catch(const std::exception &e)
{
std::clog << "exception: " << e.what() << std::endl;
}
}
int main()
{
std::set_terminate(f);
throw std::runtime_error("oh no");
return 0;
}