c++ - C++异常处理运行时是如何实现的?

标签 c++ exception error-handling language-implementation

我对 C++ 异常处理机制的工作原理很感兴趣。具体来说,异常对象存储在哪里以及它如何通过多个范围传播直到被捕获?它是否存储在某个全局区域?

由于这可能是特定于编译器的,有人可以在 g++ 编译器套件的上下文中对此进行解释吗?

最佳答案

实现可能会有所不同,但有一些基本的想法来自需求。

异常对象本身是在一个函数中创建的对象,在调用者中销毁。因此,在堆栈上创建对象通常是不可行的。另一方面,许多异常对象并不是很大。因此,如果实际需要更大的异常对象,可以创建例如 32 字节缓冲区并溢出到堆。

对于实际的控制权转移,存在两种策略。一种是在堆栈本身中记录足够的信息以展开堆栈。这基本上是要运行的析构函数和可能捕获异常的异常处理程序的列表。当异常发生时,返回执行这些析构函数的堆栈,直到找到匹配的 catch。

第二种策略将此信息移动到堆栈外的表中。现在,当发生异常时,调用堆栈用于找出进入但未退出的范围。然后在静态表中查找它们以确定抛出的异常将在哪里处理,以及在其间运行哪些析构函数。这意味着堆栈上的异常开销更少;无论如何都需要返回地址。这些表是额外的数据,但编译器可以将它们放在程序的按需加载段中。

关于c++ - C++异常处理运行时是如何实现的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/490773/

相关文章:

java - JasperReports填充编译报告时隐藏异常

c++ - 为什么使用 DrawText API 绘制时我的字体边缘不平滑?

c++ - 尝试在 C++ 中捕获二重奏

c++ - 比较 C++20 中的多态类型

python - 按照设计,属性 getter 是否应该在 python 中抛出异常?

php - 为什么 @ 运算符不抑制 CodeIgniter 中的 E_NOTICE?

javascript - 在 angularJS 项目中编写验证方法的最佳实践

javascript - 为什么 NodeJS/restify 服务器*很少*在接受时报告 EPERM?

c++ - 我可以使用覆盖非虚拟方法的方法吗?

c++ - tizen 中的 unix 日期转换