基类未捕获 C++ 异常
Posted
技术标签:
【中文标题】基类未捕获 C++ 异常【英文标题】:C++ Exception not caught by base class 【发布时间】:2019-01-24 11:10:42 【问题描述】:我正在使用 Visual C++ 2017 编译以下代码(已启用 C++17 功能)
int main()
try
// loot is some library that is linked as a dll
auto game = loot::CreateGameHandle(loot::GameType::fonv, "c:\\something\\invalid", "C:\\something\\invalid");
// throw std::invalid_argument("this works as expected");
catch (const std::exception &e)
std::cout << "caught as exception " << e.what() << std::endl;
catch (const std::invalid_argument &e)
std::cout << "caught as invalid_argument " << e.what() << std::endl;
catch (...)
std::cout << "caught by ..." << std::endl;
编译器按预期报告:
warning C4286: 'const std::invalid_argument &': is caught by base class ('const stdext::exception &') on line 8
但是,应用程序的输出是
caught as invalid_argument Given game path "c:\something\invalid" does not resolve to a valid directory.
而且它不只是改变捕获顺序或其他东西,如果我删除最后 2 个捕获块,应用程序会因为未处理的异常而崩溃。
这怎么可能?我假设这在某种程度上与编译器设置有关,这些设置使 my std::exception 与库中的一个 std::invalid_argument 继承自不同的类型 - 但为什么 my std::invalid_argument 与他们的类型相同? 有没有办法解决这个问题?因为那个库抛出了很多不同的异常类型,而我无法真正单独捕获每一个。
【问题讨论】:
这听起来很奇怪。你能用minimal reproducible example 重现这个吗?我知道这会很困难。 您应该始终从最具体的例外开始。那么loot
也是用VS2017编译的吗?当库抛出的异常由于运行时不匹配而未被其他代码捕获时,我看到了问题。
它说stdext::exception
是一个很大的危险信号。这里有些不正常。
dll是用同一个系统运行时编译的吗?
是的,战利品也是用 VS2017 构建的,但不确定它是否是完全相同的版本。这还重要吗? stdext::exception 是什么意思? Afaict 所有 std 异常都在 Visual Studio 的该命名空间中声明,然后使用 using 子句包含在 std 中。
【参考方案1】:
该死的,对不起。 事实证明,我使用的构建系统将 _HAS_EXCEPTIONS=0 添加到了预处理器定义中。这就是造成这种情况的原因。
【讨论】:
以上是关于基类未捕获 C++ 异常的主要内容,如果未能解决你的问题,请参考以下文章