第一个C ++编译器如何用C ++编写?


48

Stroustrup声称第一个C ++编译器Cfront是用C ++编写的(Stroustrup FAQ)。

但是,第一个C ++编译器怎么可能用C ++编写?

构成编译器的代码也需要进行编译,因此第一个C ++编译器不能用C ++编写,对吗?


6
en.wikipedia.org/wiki/Cfront稍微介绍了这个问题。
christofr

Answers:


57

关键就在这里:

第一个C ++编译器(Cfront)用C ++编写。为此,我首先使用C编写了一个“带有类的C”到C的预处理器。“带有类的C”是C语言,它成为C ++的直接祖先。该预处理器将“带有类的C”构造(例如类和构造函数)转换为C。这是一种传统的预处理器,无法理解所有语言,大部分类型检查由C编译器完成,并且单独翻译没有完整知识的构造。然后,我在“带有类的C”中编写了Cfront的第一个版本。

因此,Cfront的第一个版本不是用C ++编写的,而是用中间语言编写的。直接在C语言中创建C编译器和预处理器的能力导致了C语言中的许多创新(以及大量的安全漏洞)。因此,您需要编写新的preprossoror来将“带有类的C”代码转换为直接C(因为直接C可以做到)任何东西),然后使用“带有类的C”编写C ++编译器(不是您不能用C做它,只是需要一段时间),然后使用C ++编译器在其中编写更有效/更完整的编译器C ++。得到它了?


5
+1包括指向我最喜欢的事情之一的链接,该故事可以完成(不应该做)。
jwernerny 2011年

3
该编译器使用有效的C ++代码编写,但仅使用了部分完整的C ++功能,这些功能由“带有类的C”预处理器支持。它使用了全部语言的子集,因此也根据结果(Cfront的第一个工作版本)进行编译。执行完“引导程序”步骤后,他可能再也不需要使用预处理器了。
joeytwiddle

2
@jwernerny-我一直觉得这篇文章不令人满意。他掩盖了最困难和最重要的部分:“该错误将与UNIX'login'命令中的代码匹配。替换代码将错误地编译login命令,因此它将接受预期的加密密码或特定的已知密码。 ” 但是如何做到这一点?有没有被实际证明过?
2013年

3
“引出了C中的许多创新(和大量的安全漏洞)”:据我所知,这些技巧可以用任何语言(不仅是C)使用,因此任何其他语言都可以具有相同的安全漏洞。
Giorgio

2
@detly:现在听起来微不足道,但是在1983年,由于缺乏实现多样性,这是一种新颖的攻击。那时我们更信任二进制文件,部分原因是从源头编译所有内容比现在要困难得多。
Blrfl 2013年

17

它被引导了。一旦将c ++功能添加到cfront,那么cfront也可以从那时开始使用该功能(但不能实现该功能)。之所以可行,是因为cfront能够将C ++代码转换为C代码。因此,如果出现了新平台,则可以在另一个平台上使用cfront将cfront从C ++转换为C,然后使用新平台的C编译器完成从C到目标代码的编译。


9

我认为BS回答了这个问题:

第一个C ++编译器(Cfront)用C ++编写。为此,我首先使用C编写了一个“带有类的C”到C的预处理器。“带有类的C”是C语言,它成为C ++的直接祖先。该预处理器将“带有类的C”构造(例如类和构造函数)转换为C。这是一种传统的预处理器,无法理解所有语言,大部分类型检查由C编译器完成,并且单独翻译没有完整知识的构造。

然后,我在“带有类的C”中编写了Cfront的第一个版本。Cfront是传统的编译器,它完成了C ++源代码的语法和语义检查。为此,它具有完整的解析器,构建符号表,并为每个类,函数等构建了完整的内部树表示。在输出C之前,它还对其C ++构造的内部树表示进行了源代码级的优化。生成的C,不依赖C进行任何类型检查。它只是将C用作汇编程序。生成的代码毫不妥协地很快。

首先,他创建了一个称为“带类的C”的东西,该东西由一个简单的预处理器实现为C。基本上是C ++,但是预处理器很少或根本没有检查。然后,他用它来编写Cfront,这是将C ++转换为C的更强大的版本,并带有类型检查,符号表等。


1
因此,基本上,当我们编译C ++程序时,它将转换为C,然后在将其转换为C之后,再次将其编译为机器代码?
Pacerier's

@Pacerier:本来是的,但我现在不知道。
Mike Dunlavey

我不太明白你的评论。您的意思是说现在有编译器跳过第二步,仅使用C ++源代码并编译为机器代码吗?
Pacerier 2011年

7
@Pacerier:好吧,他们不会直接使用汇编语言或机器代码。通常,他们首先会转到独立于机器的中间表示形式(三重或四边形),然后对其进行分析以进行优化。从中生成汇编或机器代码。如果您读了一本有关编译器设计的书(Aho和Ullman),我相信您会发现它很有趣。
Mike Dunlavey

1
重要的是要注意,他正在构建的C ++也是现有语言的一小部分。它没有模板,没有新的库,仅使用C转换,而且如果我没记错的话,也没有例外。

2

我将添加此答案,因为没有任何答案涵盖此方面。

从技术上讲,您不需要编译代码的软件。只要您具有必要的编译器规格,就可以手动进行实际编译。这不是第一个C ++编译器的编译方式。我只是说有可能。

与汇编语言比较。早期使用它们时,没有汇编软件将汇编代码转换为机器代码。它是手工完成的,但是汇编语言为程序员提供了更好的概览。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.