异常是如何在幕后实现的?

2024-05-14 01:05:38 发布

您现在位置:Python中文网/ 问答频道 /正文

几乎每个人都在使用它们,但包括我在内的许多人只是想当然地认为它们只是工作而已。

我在找高质量的材料。我使用的语言是:java、C、C++、python、C++,所以这些是我最感兴趣的。

现在,C++可能是一个很好的开始,因为你可以在这个语言中抛出任何东西。

而且,C接近组装。如何使用纯C构造和无程序集模拟异常?

最后,我听到一个传言,谷歌员工出于速度考虑,对一些项目不使用异常。这只是谣言吗?没有他们,怎么可能有实质性的成就?

谢谢你。


Tags: 项目程序语言员工java速度感兴趣材料
3条回答

异常只是高级非本地流控制构造的更一般情况的一个特定示例。其他示例包括:

  • notifications(异常的一般化,最初来自一些旧的Lisp对象系统,现在在CommonLisp和Ioke中实现)
  • continuations(更结构化的GOTO形式,在高级、高阶语言中流行)
  • 协程(子程序的泛化,尤其在Lua中流行)
  • generatorsla Python(本质上是一种受限形式的协程)
  • 纤维(合作轻量级线程)当然还有前面提到的
  • GOTO

(我肯定还有很多我错过的。)

这些结构的一个有趣的特性是,它们在表达能力上大致相等:如果有一个one,那么可以很容易地构建所有其他结构。

因此,如何最好地实现异常取决于可用的其他构造:

  • 每个CPU都有GOTO,因此,如果必须的话,您可以随时返回到这个位置。
  • C有setjmp/longjmp,基本上是MacGyver的延续(用胶带和牙签做成的,不完全是真的,但如果你没有更好的东西,至少会让你摆脱眼前的麻烦)。
  • JVM和CLI都有自己的异常,这意味着如果您的语言的异常语义与Java/C#匹配,那么您就可以自由使用(如果不匹配,那么您就完了)。
  • 鹦鹉虚拟机既是例外又是延续。
  • Windows有自己的异常处理框架,语言实现者可以使用该框架在上面构建自己的异常。

一个非常有趣的用例,异常的用法和异常的实现都是Microsoft Live Lab的Volta项目。Volta的目标是通过按下按钮为Web应用程序提供架构重构。因此,只需在.NET代码中添加一些[Browser][DB]属性,就可以将一层web应用程序转换为两层或三层应用程序,然后代码将自动在客户端或数据库中运行。为了做到这一点,.NET代码显然必须转换成JavaScript源代码。

现在,您可以用JavaScript编写一个完整的VM并在未修改的情况下运行字节码。(基本上,CLR从C++到JavaScript。)实际上有一些项目(例如HutruBy VM),但是这是低效的,并且与其他JavaScript代码不能很好地互操作。

因此,他们编写了一个编译器,将CIL字节码编译成JavaScript源代码。然而,JavaScript缺乏.NET所具有的某些特性(生成器、线程,以及这两个异常模型并非100%兼容),更重要的是,它缺乏编译器编写器love(或者GOTO或continuations)所具有的某些特性,这些特性可用于实现上述缺失的特性。

但是,JavaScript确实有异常。因此,他们使用JavaScript异常来实现Volta Continuations,然后使用Volta Continuations来实现.NET异常.NET生成器甚至.NET托管线程(!!!)

所以,回答你最初的问题:

How are exceptions implemented under the hood?

讽刺的是,除了例外!至少在这个非常特殊的情况下,无论如何。

另一个很好的例子是Go邮件列表中的一些异常建议,它们使用goroutine实现异常(类似于并发协同路由和CSP进程的混合)。另一个例子是Haskell,它使用monad、惰性计算、尾部调用优化和高阶函数来实现异常。一些现代CPU也支持基本构建异常的ing块(例如专门为Azul系统Java计算加速器设计的Vega-3cpu)。

在他的书《C接口和实现:创建可重用软件的技术》中,D.R.Hanson使用一组宏和setjmp/longjmp在纯C中提供了异常的良好实现。他提供了尝试/提高/ / /最后宏,它可以模仿几乎所有C++异常所做的事情。

代码可以仔细阅读here(查看except.h/except.c)。

p.S.是你关于谷歌的问题。他们的员工实际上被允许在新代码中使用异常,而在旧代码中禁止使用异常的官方原因是,它已经这样写了,混合样式是没有意义的。

我个人认为C++没有例外不是最好的主意。

这里是C++异常的常见实现方式:
http://www.codesourcery.com/public/cxx-abi/abi-eh.html

它适用于安腾体系结构,但这里描述的实现也适用于其他体系结构。注意,它是一个长文档,因为C++异常是复杂的。

下面是LLVM如何实现异常的一个很好的描述:
http://llvm.org/docs/ExceptionHandling.html

由于LLVM是许多运行时的公共中间表示,因此所描述的机制可以应用于许多语言。

相关问题 更多 >