C编译器参考实现

hes*_*bar 1 c compiler-construction winapi gcc glibc

有多种语言具有其编译器/库的参考实现,但为什么C没有参考实现?
我知道GCC和glibc被广泛使用,微软有他们也使用的版本,但为什么不是一个主要的实现,例如python?(是的,我知道还有其他实现,但有一个MAIN/Reference python)是
不是与Linux和Windows等操作系统在C中实现至少部分API的事实有关吗?谢谢.

Win*_*ute 9

我想,这实际上更像是历史而非技术问题.简短的回答是:有一种,有一种.它没有采取.答案很长,取决于你想要进入多少细节.

C老了.我的意思是,python也很老,但C 真的很老了.Dennis Ritchie在20世纪60年代后期在贝尔实验室共同攻击了它的第一个版本,他这样做是为了不必在汇编或B中编写UNIX(这是一个现在被遗忘的系统编程语言C被解决的一些缺点).

这可以说是与当今语言设计完全不同的方法:C是为编写UNIX而编写的.为了设计一个漂亮而干净的系统编程语言,没有人坐下来设计C语言; 这些家伙想要编写一个操作系统并构建一个工具,使他们能够更轻松地完成这项工作.

但是,这个贝尔实验室C编译器是一种参考实现,因为C基本上是C团队写入编译器的内容.然后是便携式C编译器,它本来可以让C更容易移植到新平台,而这本名为"C编程语言"(又名非正式的K&R C规范)的书,以及C开始流行,一切都很顺利.事情变得复杂了.

C在它仍然存在的时候变得很受欢迎......让我们做慈善事业并说"有一些改进的余地".当然它有; 每种语言都有改进的余地.对于初学者来说,没有真正的标准库.在编译时没有检查函数参数,函数无法返回voidstructs,那种事情.它的边缘仍然很粗糙.

但现在不只是贝尔实验室,哦不.现在有几十家供应商,他们都对pcc或本土编译器进行了改编,并且提出了许多关于C可以改进的方法的很好的,有时甚至不那么好的想法.他们对设计语言的兴趣也不如设计一种可以简化实际工作的工具.因此,他们编写了自己的语言扩展,有时这些扩展与其他人想出的扩展并不相符.

现在,在这一点上很容易面对,并问为什么他们不仅仅是更好地协调语言开发,但实际上并非那么简单.互联网还不存在,所以他们不仅可以建立一个IRC频道来讨论内容,而且......好吧,与今天相比,编程语言并不是唯一一个混乱的东西.

今天,大多数计算机都非常相似.我们都将负整数表示为二进制补码,字节几乎总是8位宽,指针只是内存地址.当时情况并非如此,当你考虑到当C被标准化时,仍然有机器使用了一个补码或有符号幅度,你就知道为什么签名溢出在C中是未定义的.你有没有见过旧DOS程序的C代码?他们有近距离和远距离指针的概念,因为旧的16位x86计算机需要特殊的分段寄存器来处理超过64KB的RAM.有几个编译器为此构建了C扩展,但请相信我,你非常非常高兴C今天不包含这个概念.苏联建造了一台平衡的三元计算机,虽然我不确定它是否有C支持.简而言之,硬件环境也很混乱,对于一种接近金属的语言而言,这是一件大事.

因此,每个人都做了他们必须做的事情,并且一般(尽管不总是)尽力而为,但语言必然会发生分歧.语言核心最终在1989年被标准化(当承办者......坚持,错误的一年)带回一些相似的秩序,并且在这些编译器开始融合之后几年.然而,一些旧的扩展将永远不会消失,因为向后兼容始终是一个问题 - 考虑python 3被采用的速度有多快 - 并且有一些接近金属的问题需要针对该语言来解决有用但不能明智地写入规范,因为它们不可移植,例如调用约定.

你有它.C具有语言规范而不是参考实现的原因主要是历史性的,部分原因是它必须运行的不同机器的微妙之处.

我想有可能开发一个官方的参考实现(至少对于一些常见的平台),但我也相信它的价值会有所限制.毕竟,C标准必须保留一些未定义的东西,因为它无法知道底层机器的确切性质,因此只要您输入的代码格式正确,所有其他实现只会像参考实现一样运行.对于格式良好的代码,通常的C实现(即gcc,clang,MSVC)通常表现相同,因此您可以使用其中任何一个.