异常处理程序的不良实现会在进入 try 子句时为运行时堆栈上的每个 try 子句推送某种异常处理程序块,并在退出 try 子句时将其弹出。保存最近推送的异常处理程序块的地址的位置也被维护。通常,这些异常处理程序链接在一起,因此可以通过从最新版本到旧版本的链接找到它们。当发生异常时,会找到指向最后推送的 EH 处理程序块的指针,并检查该“try”子句的 EH 案例的处理。对 EH 案例的命中会导致堆栈清理回到被推送的 EH 点,并且控制转移到 EH 案例。没有命中 EH 会导致找到下一个 EH,并重复该过程。Windows 32 位 SEH 方案是该方案的一个版本。
这是一个糟糕的实现,因为即使没有发生异常,程序也会为每个 try 子句(push 然后 pop)支付运行时代价。
好的实现只是记录一个出现 try 子句的范围表。这意味着进入/退出 try 子句的开销为零。(我的PARLANSE并行编程语言使用了这种技术)。异常在表中查找异常点的PC,并将控制权交给表选择的EH。EH 代码会根据需要重置堆栈。又快又漂亮。我认为Windows 64位EH就是这种类型,但我没有仔细看。
[编辑 2020 年 4 月:最近刚刚测量了 PARLANSE 异常的成本。如果没有例外,则为 0nS(按设计);在 3Ghz i7 上从“抛出”到“捕获”再到“确认”(结束空捕获)需要 25ns。OP 为最简单的类型添加了一个测量 C++ 异常处理大约 1000ns 的链接,以及一个字面上的非标准处理方案,该方案以 57ns 的时间处理异常或无异常;C++ 版本的 CPU 时钟速率稍慢,因此这些数字仅用于粗略比较。]