为什么在 macOS M1 环境下,`std::invalid_argument` 没有被 no-rtti 捕获?

问题描述 投票:0回答:1

今天我在 C++ 中捕获异常时遇到了一个奇怪的行为,有人可以向我解释一下吗?代码片段

#include <iostream>
#include <string>
#include <exception>


int main() {
  try {
    std::stod("notanumber");
  } catch (const std::invalid_argument&) {
    std::cerr << "std::invalid_argument" << std::endl;
  } catch (const std::out_of_range&) {
    std::cerr << "std::out_of_range" << std::endl;
  } catch (const std::exception&) {
    std::cerr << "Caught by ancestor" << std::endl;
  } catch (...) {
    auto ptr = std::current_exception();
    auto type = __cxxabiv1::__cxa_current_exception_type();
    std::cerr << type->name() << std::endl;
    std::cerr << "..." << std::endl;
  }
  return 0;
}

写入输出

St16invalid_argument
...

环境详情

C++ 14, disabled RTTI
Clang 13.1.6 arm64-apple-darwin-21.6.0
macOS Monterey 12.6

我希望在第一个 catch 块上捕获异常

更新。即使是最简单的捕获对我来说对环境也不起作用

try {
  std::stod("notanumber");
} catch (const std::invalid_argument&) { // not caught
  std::cerr << "std::invalid_argument" << std::endl;
}
c++ macos c++14 std rtti
1个回答
0
投票

C++ 异常处理依赖于 RTTI,其原因与dynamic_cast 依赖于 RTTI 的原因相同。当抛出异常时,堆栈将被展开,并且实现会搜索匹配的异常处理程序。

对于 apple clang 默认使用的 libc++,确定处理程序是否匹配是通过

can_catch
来完成的,这是 type_info 对象上的虚拟方法。确定两个类类型信息结构是否匹配涉及其他检查:检查 type_info.name() 和dynamic_cast。

© www.soinside.com 2019 - 2024. All rights reserved.