4

由于嵌入式系统编程,我接触了 C,我认为它是该领域的一门很棒的语言。但是,为什么它被用来编写编译器呢?如果说gcc用C/C++实现的原因是当时好的语言不多,那么clang走同样的路(使用C/C++)就没有任何借口了。

是出于性能原因吗?与编译语言相比,大多数解释语言要慢一些,但我想在 CoffeeScript (JavaScript) 中这种差异几乎可以忽略不计,因为 Node.js。

从开发人员的角度来看,我认为使用高级语言编写一个编译器要容易得多。不幸的是,大多数编译器都是用 C/C++ 编写的。仅仅是因为遗留代码吗?

回复评论:

  • 自举只是说明这种语言功能强大到可以编写一个编译器的一种方式。这不应该是我们选择语言来实现编译器的主要原因。

  • 我同意下面给出的猜测,“大多数编译器开发人员会回答,因为大多数编译器相关工具(bison、yacc)都会发出 C 代码”。然而,GCC 和 Clang 都没有使用生成的解析器,他们自己实现了一个。这个前端进程独立于目标架构,不应该是 C/C++ 的强项。

  • 人们或多或少一致认为,性能是关键因素之一。事实上,即使对于 GCC 和 Clang,构建一个合理大小的 C 项目(Linux 内核)也需要很多时间。是因为前端还是后端。我不得不承认我在编译器后端方面没有太多经验,因为我们用生成的 LLVM 代码完成了编译器课程。

4

5 回答 5

12

由于嵌入式系统编程,我接触了 C,我认为它是该领域的一门很棒的语言。

是的。它比 Java 好。

但是,为什么它被用来编写编译器呢?

不问开发人员就无法回答这个问题。我怀疑他们中的大多数人会告诉您,常见的编译器编写软件(yacc、flex、bison 等)会生成 C 代码。

如果 gcc 的原因是没有很多好的语言,那么clang 没有任何借口。

GCC 不是一种编程语言,Clang 也不是。它们都是 C 编程语言的实现。

是出于性能原因吗?

不要将实现与规范混淆。速度是您的编译器和计算机引入的属性,而不是编程语言。GCC 恰好产生了相当高效的机器代码,这可能会影响开发人员使用 C 作为他们的主要编程语言......但十年后*,node.js 产生的机器代码可能比 GCC 更高效。不要忘记,StackOverflow 是永远的。

* 可以,但很可能不会。有关更多信息,请参阅下面的 Ira Baxters 评论。

与编译语言相比,大多数解释语言要慢一些,但我想在 CoffeeScript (JavaScript) 中这种差异几乎可以忽略不计,因为 Node.js。

同样,解释或编译不是语言的选择,而是语言的实现。例如,GCC 和 Clang 选择将 C 编译为机器码。Ch 和 CINT 是两个将 C 代码直接转换为行为而不是机器代码的解释器。Java 曾经也主要使用解释进行翻译,但现在主要编译成 JVM 字节码。Javascript 似乎也正在逐步转向主要编译。谁知道?也许你会在十年后看到主要用 Javascript 编写的编译器......

从开发人员的角度来看,我认为使用高级语言编写一个编译器要容易得多。

所有这些编程语言在技术上都是高级别的。它们主要是根据抽象机器定义的;他们的水平当然不低。

不幸的是,大多数编译器都是用 C/C++ 编写的。

我不认为 C++ 用于编写软件是不幸的。这不是一种糟糕的编程语言。

仅仅是因为遗留代码吗?

我想遗留代码可能会影响程序员的决定。最后,正如我所说,您必须询问开发人员。他们可能只是决定使用 C 或 C++,因为 C 或 C++ 是他们最喜欢的编程语言……你为什么说英语?

于 2013-06-20T14:59:47.167 回答
3

我看到很多原因:

  • 没有优雅的方式来处理 Javascript 中的位精确代码
  • 您不能用 Javascript 轻松编写二进制文件,因此编译器的汇编器部分必须使用更底层的语言
  • 巨大的 JS 代码库在内存中加载非常重(那是纯文本,还记得吗?)
  • 为编译器编写优化例程是 CPU 密集型的,这与 Javascript 还不是很兼容
  • 您将无法使用它(bootstrap)编译您的编译器,因为您需要一个 Javascript 解释器作为您的编译器。引导阶段不会是“纯粹的”:
    JS Compiler compiles NodeJS -> NodeJS runs your new Compiler -> new JS Compiler
于 2013-06-20T14:42:10.410 回答
3

编译器通常是非常复杂的软件。前端部分非常简单(解析),但后端部分(调度、代码生成、优化、寄存器分配)涉及 NP 完全问题(当然编译器试图近似解决这些问题)。因此,在 C 中实现将有助于编译时间。C 也非常擅长按位运算符和其他低级别的东西,这对于编写编译器很有用。

请注意,并非所有编译器都是用 C 编写的。例如,Haskell GHC 编译器是使用自举技术用 Haskell 编写的。

Javascript 是异步的,不适合编译器编写。

于 2013-06-20T14:37:45.120 回答
2

gcc 主要在 C 中实现,但并非所有编译器都是如此,包括一些非常标准的编译器。用它编译的语言实现编译器是一种常见的模式。 ghc主要是用 Haskell 编写的。最新版本的guile具有一个主要在 Scheme 中实现的编译器。

于 2013-06-20T14:45:31.320 回答
1

不,coffeescript 等人仍然比本地编译(和优化)的 C 代码慢得多。即使您采用能够优化的 javscript 子集(asm.js),它仍然是原生 C 的两倍。

当人们说 node.js 与 C 代码一样快时,您所听到的意思是它与执行其他操作(例如从磁盘读取、等待网络数据等)的整个系统的一部分一样快。在这些系统中CPU 未得到充分利用(尤其是当今超高速 CPU),因此性能问题不是语言的原始处理能力。因此,如果 node.js 服务器都卡在等待网络调用返回数据,则它们与 C 服务器完全一样快。用 node.js 编写的系统类型需要大量等待网络,这就是人们使用 node.js 的原因。用 C 编写的系统类型不适合用 node.js 编写

于 2013-06-20T14:38:10.137 回答