【问题标题】:Why doesn't C# compile directly to machine code?为什么 C# 不直接编译成机器码?
【发布时间】:2015-01-30 16:41:18
【问题描述】:

CIL 是一种面向对象的汇编语言,完全是 基于堆栈。它的字节码被翻译成本机代码或——大多数 通常——由虚拟机执行。

为什么我们需要 CIL?不能将 C# 翻译成本机代码而不是 CIL 吗? 如果所有 .Net 语言都编译为 CIL,为什么不使用 C# 而不是 IL? CIL 比 C# 或 VB 更具表现力吗?

【问题讨论】:

  • “为什么 CIL 比 C# 或 VB 更具表现力?” - 你从哪里得到 CIL 比 C# 或 VB 更具表现力的想法,你在这里所说的 expressive 到底是什么意思?
  • @O.R.Mapper - 有个结构可以在 IL 中表达,但在任何一个 IIRC 中都没有实现。
  • @O.R.Mapper CIL 允许您与 CTS 允许的所有编程结构进行交互
  • @MartinSmith, Gui_C:好的,如果那(功能范围)是“表达性”的意思,那么您可能有一点。我宁愿知道术语“富有表现力”类似于“直观易懂”(例如,foreach 循环在迭代某些东西方面比带有索引的传统 for 循环更具“表现力”)。即,“表现力”=“代码的意图表达的直观程度如何?”因此,我的问题是在这种情况下对“表达性”的确切定义。
  • 当字节码被“虚拟机执行”时,它也会首先被翻译成本地代码。使您的开场白(?)具有误导性和不精确性。

标签: c# compilation cil intermediate-language


【解决方案1】:

问题更笼统:为什么我们需要中间语言?为什么许多现代高级语言编译成中间形式,然后解释/JITed 成本机代码?

首先,请注意,不仅 .NET 使用它自己的中间语言。 Java has one as well as many, many other languages/platforms.

有几个原因支持这种方法。最重要的是中间语言抽象了运行时环境的架构。它不绑定到任何特定架构,而是使用一些抽象(例如,在 CIL 中虽然物理机器有寄存器但没有寄存器,但在 CIL 中有局部变量,这些变量通常 JITed 到物理寄存器)。

抽象意味着更容易推理安全性能。例如,他们有一个正式的定理,即 CIL 是类型安全的,由 J. Kennedy 和 D. Syme 证明。此外,抽象中间形式可能比平台原生代码更紧凑。另一个好处是实际执行可以使用有关当前系统的信息,例如,在 32 位和 64 位环境中执行的相同 CIL 可以 JIT 到不同的本机代码,反映 64 位寄存器的可用性。

http://en.wikipedia.org/wiki/P-code_machine

C# 不是中间语言的好选择。虽然 CIL 和 C# 都是图灵完备的,这意味着任何其他编程语言都可以编译成 C# 和 CIL,但 C# 只是 太抽象,太高级了。因此,将一些非对象语言编译成 C#(函数式语言、声明性语言)可能需要大量 C# 代码,并且与所有高级语言都针对相同、抽象但仍然目标的场景相比,实际执行会更慢相当低级的中间语言,可以有效地 JITed 到本机代码。

这就是 CIL 包含 C# 中不存在的功能的原因,反之亦然。例如,CIL 支持 方法指针尾调用,而 C# 不需要两者——但这样一些函数式语言可以以更有效的方式进行翻译。另一方面,C# 具有 CIL 中不存在的 properties 的概念 - 这是因为属性可以被视为只是一种 句法糖,它不会引入任何表达性,而是而是某种语言的方便

【讨论】:

  • "在 CIL 中没有寄存器,虽然物理编译器有寄存器" 你的意思是“物理计算机”吗?
  • 此外,CIL 确实有一些属性(参见 ECMA-335 的 §II.17)。虽然只是元数据,但在 CIL 中无法访问该属性,必须调用访问器方法。
猜你喜欢
  • 2020-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-12
  • 1970-01-01
  • 2010-11-26
  • 2018-12-05
  • 2018-06-16
相关资源
最近更新 更多