C语言这么厉害,它自身又是用什么语言写的?
很多人学C语言的时候都会冒出一个问题:
C语言这么底层、这么强大,那C语言自己是用啥写的?
先说结论,C语言的第一个编译器,不是用C写的。
这不废话,用C写C编译器,那C编译器从哪来?先有鸡还是先有蛋?
1,C语言编译器是编译成二进制文件了,编译成二进制文件后就跟开发语言无关了。
这就跟机床一样,第一台机床肯定不是用机床加工的,但后面更好的机床,肯定是用前面的机床加工的,用其他语言写个编译器,支持基本语法后,就可以用这个编译器开发新的编译器,增加新特性。
编译器也是类似。 你只需要有一个能跑的编译器,就能用它来造下一个更好的编译器。
2,那C语言第一个编译器到底用什么写的?
这得回到1972年,贝尔实验室。
C语言是Dennis Ritchie开发的。但第一个C编译器,是用 B语言 写的。
B语言是C的前身,同样是Ritchie和Ken Thompson搞出来的。而B语言的编译器,最早是用 汇编 写的。
所以整个链条是这样的:
汇编 → B语言编译器 → C语言编译器 → 现代C语言编译器
3、 用C语言重写C编译器
到了1973年,C语言已经成熟得差不多了,Ritchie做了一个历史性的决定: 用C语言重写C编译器本身。
这就是计算机史上著名的" 编译器自举 "。
过程大概是这样的:
用B语言写的C编译器,编译新写的C版本编译器源码
跑起来,得到一个新的C编译器可执行文件
用这个新编译器再编译一遍自己的源码
验证两次结果是否一致
自己编译自己。
开始是汇编,C语言规范是可以自举的,所以用汇编实现了最开始的几个特性后,就可以用c来写剩下的。编译器的问题就能回答和解决了。
4,编译器是把一种代码映射为另一种代码 所以可以用高级语言写。
就算用Python fsharp这样的语言都能写C编译器。在C语言之前,已经出现了别的高级语言,例如Pascal,那就可以用Pascal来写一个C语言的编译器。
高级语言的鼻祖Fortran,它的编译器是汇编写的。Pascal的第一个编译器据说是Fortran写的。有了这些,才有后来的C。
5,早期写代码,内存极其稀缺。
1970、80年代,很多机器连64KB内存都装不满。在这种条件下写复杂功能,根本轮不到高级语言出场, 汇编才是主力 。
Apple II时代大部分游戏是纯汇编写的。很多程序员连汇编器都没有,要自己手写机器码,6502的那堆寻址码得背得滚瓜烂熟,相对地址还得自己掰着手指算十六进制。
那个年代的程序员,是真的硬。
6、一门新语言的编译器,往往是在"旧硬件+旧语言"上先搞出来的。
Macintosh 128k发布之前,给它开发软件的程序员,用的是更早的机器。新硬件、新系统,先在旧平台交叉编译,这在当时是常规操作。
所以你看,C语言是厉害,但它也是一步一步从汇编和B语言里走出来的。
编译器不神秘,它本质上就是把一种代码映射成另一种代码的工具。理论上,哪怕你用Python、F#,都能写出一个C语言编译器。
只要逻辑正确,用什么语言写都行。
重要的不是写编译器的语言,而是那个坐在贝尔实验室里、真的动手把它造出来的人。
