c++ - 异常是如何转移到寻找处理程序的?

标签 c++ exception implementation

当抛出异常时,会启动堆栈展开,直到遇到处理代码,但我不太清楚整个过程的机制。

1 - 异常存储在哪里?我不是指实际的异常对象,它可能很大,例如有一个消息字符串或其他东西,但如果你愿意的话,还有实际的引用或指针。它必须是某个统一的存储位置,以便它能够在堆栈展开并到达处理位置时继续下降?

2 - 程序流如何确定它是否必须展开特定函数框架并调用与程序计数器指示位置关联的适当析构函数或在进一步展开之前寻求异常处理?

3 - 如何在抛出的内容和正在发生的异常之间进行实际检查?

我知道答案可能包括特定于平台的内容,在这种情况下,我们将不胜感激。不过,无需超越 x86/x64 和 ARM。

最佳答案

这些都是实现细节,将在设计异常处理机制的(重要的)过程中决定。我只能简要说明人们可能(或可能不会)选择如何实现这一点。

如果您想要一个实现的详细描述,您可以阅读 Itanium ABI 的规范被 GCC 和其他流行的编译器使用。

1 - 异常对象存储在一个未指定的地方,必须持续到异常被处理为止。指针或引用像任何其他变量一样在异常处理代码中传递,然后通过某种类似于传递函数参数的机制传递给处理程序(如果它采用引用)。

2 - 有两种常见的方法:静态数据结构将程序位置映射到有关堆栈帧的信息;或动态堆栈式数据结构,其中包含有关事件处理程序和需要销毁的重要堆栈对象的信息。

在第一种情况下,在抛出时它会查看该信息以查看是否有任何本地对象要销毁,以及是否有任何本地处理程序;如果没有,它将在本地栈帧上找到函数返回地址,并将相同的过程应用于调用函数的栈帧,直到找到处理程序。一旦找到处理程序,CPU 寄存器就会更新以引用该堆栈帧,程序可以跳转到处理程序的代码。

在第二种情况下,它将从堆栈结构中弹出条目,使用它们告诉它如何销毁堆栈对象,直到找到合适的处理程序。一旦找到处理程序并销毁所有展开的堆栈对象,它就可以使用 longjmp 或类似的机制跳转到处理程序。

其他方法也是可能的。

3 - 异常处理代码将使用某种数据结构来识别类型,允许它将抛出的类型与处理程序的类型进行比较。继承有点复杂;测试不能是简单的比较。我不知道任何特定实现的细节。

关于c++ - 异常是如何转移到寻找处理程序的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26652963/

相关文章:

c++ - Miller-Rabin 素数测试 FIPS 186-3 实现

c++ - 指针数组栈实现

c++ - 为什么我的程序在Windows上运行得很好,但在Linux上却运行不好?

c++ - std::endl << std::flush 有目的吗?

PHP - 自定义异常错误

java - 未给出输入时不会引发异常

c++ - 如何在 Visual Studio 2010 中使用 C++(使用非托管代码)创建分步向导

c++ - 读取 OpenMesh 文件时断言 block_size == b 失败

c# - 不寻常的异常行为?

ios - 如何在我的游戏中使用 iTunes 预览?