如果您可以忍受1所暗示的可移植性限制,那么您可能会接受以下终止处理程序:<cxxabi.h>
backstop()
主文件
#include <iostream>
#include <exception>
#include <stdexcept>
#include <cstdlib>
#include <cxxabi.h>
void backstop()
{
auto const ep = std::current_exception();
if (ep) {
try {
int status;
auto const etype = abi::__cxa_demangle(abi::__cxa_current_exception_type()->name(), 0, 0, &status);
std::cerr << "Terminating with uncaught exception of type `" << etype << "`";
std::rethrow_exception(ep);
} catch(const std::exception& e) {
std::cerr << " with `what()` = \"" << e.what() << "\"";
} catch(...) {}
std::cerr << std::endl;
}
std::abort();
}
int main(int argc, char *argv[])
{
std::set_terminate(backstop);
if (argc > 1) {
throw argv[1];
} else {
throw std::runtime_error("I am too tired to carry on");
}
return 0;
}
这将始终报告未捕获异常的类型,如果该类型派生自
std::exception
,它还将报告该what()
异常的类型。例如
$ g++ --version
g++ (Ubuntu 9.3.0-10ubuntu2) 9.3.0
...
$ g++ -Wall -Wextra -pedantic main.cpp; ./a.out Whoops!
Terminating with uncaught exception of type `char*`
Aborted (core dumped)
$ clang++ --version
clang version 10.0.0-4ubuntu1
...
$ clang++ -Wall -Wextra -pedantic main.cpp; ./a.out
Terminating with uncaught exception of type `std::runtime_error` with `what()` = "I am too tired to carry on"
Aborted (core dumped)
请注意,您可能会避免调用set_terminate(backstop)
- 可以想象,这可能会在大型复杂程序的其他地方被取消 - 并确保任何逃避主体的异常main
都被函数 try-block捕获,即替换main
为:
int main(int argc, char *argv[]) try
{
if (argc > 1) {
throw argv[1];
} else {
throw std::runtime_error("I am too tired to carry on");
}
return 0;
}
catch(...) {
backstop();
}
该程序将像以前一样运行。
[1] 你至少会拥有 g++、clang++、icc;你不会有 MS C++