问题描述
我对 C++ 异常处理机制的工作原理很感兴趣.具体来说,异常对象存储在哪里以及它如何通过多个范围传播直到被捕获?它是否存储在某个全局区域?
I am intrigued by how the C++ exception handling mechanism works. Specifically, where is the exception object stored and how does it propagate through several scopes until it is caught? Is it stored in some global area?
由于这可能是特定于编译器的,有人可以在 g++ 编译器套件的上下文中解释这一点吗?
Since this could be compiler specific could somebody explain this in the context of the g++ compiler suite?
推荐答案
实现可能会有所不同,但有一些遵循需求的基本思想.
Implementations may differ, but there are some basic ideas that follow from requirements.
异常对象本身是在一个函数中创建的对象,在其调用者中销毁.因此,在堆栈上创建对象通常是不可行的.另一方面,许多异常对象并不是很大.因此,如果确实需要更大的异常对象,可以创建例如一个 32 字节的缓冲区并溢出到堆.
The exception object itself is an object created in one function, destroyed in a caller thereof. Hence, it's typically not feasible to create the object on the stack. On the other hand, many exception objects are not very big. Ergo, one can create e.g a 32 byte buffer and overflow to heap if a bigger exception object is actually needed.
至于控制权的实际转移,存在两种策略.一种是在堆栈本身中记录足够的信息以展开堆栈.这基本上是要运行的析构函数和可能捕获异常的异常处理程序的列表.当异常发生时,返回执行那些析构函数的堆栈,直到找到匹配的捕获.
As for the actual transfer of control, two strategies exist. One is to record enough information in the stack itself to unwind the stack. This is basically a list of destructors to run and exception handlers that might catch the exception. When an exception happens, run back the stack executing those destructors until you find a matching catch.
第二种策略将此信息移动到堆栈外的表中.现在,当发生异常时,调用堆栈用于找出进入但未退出的范围.然后在静态表中查找它们以确定将在哪里处理抛出的异常,以及在它们之间运行哪些析构函数.这意味着堆栈上的异常开销更少;无论如何都需要返回地址.表是额外的数据,但编译器可以将它们放在程序的按需加载段中.
The second strategy moves this information into tables outside the stack. Now, when an exception occurs, the call stack is used to find out which scopes are entered but not exited. Those are then looked up in the static tables to determine where the thrown exception will be handled, and which destructors run in between. This means there is less exception overhead on the stack; return addresses are needed anyway. The tables are extra data, but the compiler can put them in a demand-loaded segment of the program.
这篇关于C++异常处理运行时是如何实现的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!