注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

天地不仁,以万物为Googol!

天行有常,不以物喜,不以己悲……

 
 
 

日志

 
 

蓦然回首:C++历史上的五组五魁首,第三组:永远最重要的五个C++软件

2006-10-10 23:18:42|  分类: 翻译 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

原文:http://www.artima.com/cppsource/top_cpp_software.html

 

作者:Scott Meyers

 

在我的头两篇文章中,列举了我认为的对C++界最重要的书籍和非书籍出版物。

 

在这个部分,我把我的注意力转到了永远最重要的C++软件上。

 

在写C++程序时,你需要一些辅助工具。在我看来,这些辅助工具才是(以后也是)与C++有关的最重要的软件。你可以想象,由于使用C++开发了某个惊世骇俗的应用程序,而使其他人在今后的项目中也选用这一语言。但实际上,我从没看到有这样的事情发生。关于语言的最重要的软件,应该是开发者们每时每刻都在用的东西:编译器和库。对设计语言来说,如何实现库要比如何实现应用更合适。

 

我选出了五个C++历史中最重要的软件,按第一次出现的时间顺序排列。他们是:

 

- Cfront,AT&T贝尔电话实验室,1989-1993。在最开始,只有Cfont,原始的编译器。它确实是个编译器,但它以C代码作为目标代码,所以它经常被认为是把C++转换到C的预编译器。另外,也很难想象用它来除错(Debug),因为,至少在1988年我开始用它的时候,还没有C++调试器。我们的老先锋们只能使用C调试器,并且尝试手动解释连接名(unmangle name)。(比如,在调试器里识别出__pl__1Aff是指C++源码中的某个加法运算符函数

 

事实上,Cfront生成C代码,这件事情至少有两个好处。第一,很容易将Cfont移植到新的平台,因为C编译器到处都有。这个可以使C++更容易扩展到别的环境。第二,用户可以分析生成的C代码来判断编译时发生的事情。在当时,很多初次使用C++的人希望能知道C++是怎么做的,而生成的C代码正好可以帮助了解语言的原理。而且这样也很安全。如果你可以很容易的看到它的工作(至少和用于生成机器代码的C语言一样简单),你也就不用担心它会在你的眼皮底下捣鬼了。

 

直到1990年,Cfront不仅仅编译代码,它实际上还确定了C++的标准。C++来自AT&T,而Cfront来自AT&T中的C++工作组,所以Cfront所做的事情一定是正确的。在那个时候,其他C++编译器的实现者坚持跟随Cfront的行为,甚至复制了Cfront的错误。在《Annotated C++ Reference Manual》(ARM)出版后,Cfront才逐渐褪去作为参考实现的角色,尤其是Herculean在Cfront中加入了对异常处理的支持之后。

 

最后一版的Cfront于1993年发布,但是它的精神延续至今。Edison Design Group——一个在商业上很著名的公司,制造最符合标准的C++前端——在2006年七月的一片文档中宣布,他们支持Cfront兼容模式。我个人认为,有不少嵌入式平台本身还没有原生C++编译器,这些平台上的不少项目都使用了Cfront来实现C++编译,但这只是我个人的一种看法。

 

- GCC,GNU组织,1987-今。GNU很早就进入了C++领域,并且发布了第一个能直接生成本地代码的编译器(作为对比,Cfront只是从C++翻译为C)。过了这么多年后,GNU的编译器已经成为了跨平台应用的首选。它本身是个跨平台的编译器,这也使它在嵌入式系统开发中很流行。GCC本身是个编译平台,支持多种前端(比如C,C++,FORTRAN,等等)和后端(对不同的目标平台)。其C++的版本是g++。

 

在早期,Michael Tiemann推动了g++的发展。我记得当时我提交了一个g++的错误报告,并且,很快,Tiemann就给了我回复。回复中包括了一份g++原理实现的最新材料,并要求我添加这份材料,重新编译,看看我提到的错误是不是已经改正了。我印象里,那个问题依然存在,但是,编译器的作者直接给你一份更正的代码,并希望你自己修改,这个是很特别的。附带提一句,Tiemann在1989年创立了Cygnus Support,我相信这家公司是基于免费软件的第一家公司。(有报道指出,在更早的时候,Tiemann有时在浴缸里主持Cygnus的会议)。

 

g++是个开源软件,因此C++社区可以以任何目的自由察看g++的前端实现是否符合标准。我不知道有哪个开源工具(比如,lint,重构等工具)是基于g++的代码开发的,目的是解析所有g++能够解析的东西。已经有工具可以解析C++的声明(比如,gccxml),但是,就我目前所知,没有一个工具可以同时解析声明和定义(尤其是对函数体的定义)。这只能说g++的前端很特别,并且虽然我对其具体实现知道的不多,但我怀疑其实现并不很好。着很可惜,因为C++开发者应该需要一组大型工具,但是阻碍实现这些工具的障碍是解析(注1)C++源码的能力,而这个阻碍很少有人能够跨过去。

 

- Visual C++,Microsoft,1992-今。Visual C++是C++能够成功地重要原因之一,同时,也是阻碍C++发展的重要阻力之一。虽然Bjarne Stroustrup主张“没有人知道大部分C++开发者在做啥(注2)”,但是我有点怀疑,如果把这个星球上C++程序员集结起来,让他们选出他们工作中最常用的编译器,那么他们绝大部分都会提到VC++。就冲这个,VC++已经对C++很重要,而且这种重要性还会继续下去。此外,Microsoft的旗舰产品(比如,操作系统和Microsoft Office应用程序)也全部或者大部分用C++完成,并用Visual C++编译。这个,也使VC++成为C++世界重要的一部分。这个公司信任C++,并且这种信任促使其开发工具和API来支持C++,而这,最终推动很多Windows开发者转移到C++上。在90年代末期,C++(令我震惊和沮丧的)以“Microsoft的语言”(注3)而闻名。Visual C++依然是C++世界中的主要参与者。对众多程序员来说,Visual C++就是C++。(看来老外也有的是分不清语言和IDE的。)

 

很可惜,多年以来,Microsoft的编译器实现并不符合标准。直到1998年,这并不是个问题,因为那时并不需要强制遵循哪个标准,而且,其它的编译器提供商在实现上也都有保留自己的特色。不过,Visual C++ 6(VC6)在1998年发布,大约在C++标准定稿后一年。VC6与标准符合程度非常差,但在那时候,这并不是个严重的问题,因为使用标准定义的C++“新特性”的程序员少之又少。但是直到2002年(那时发布了VC7),VC6始终是Microsoft唯一正式发布的最新的编译器,而且与最初发布时相比,编译器本身没有任何大的改动,与标准不兼容的问题就变得非常严重了。至少,我们认为,应该更早发布补丁包,且应该主要改进对标准中主要更新的程序库(比如,与标准更兼容的STL)的兼容性问题。2003年发布的Visual C++(VC7.1)终于解决了大部分与不符合标准的问题,但是,在从VC6到VC7.1的六年中,使用VC++的跨平台开发者花费了大量的经历,用来处理VC++不支持的特性,比如通过有条件编译(比如基于代码碎片)来实现模版偏特化。此外,直到今天,仍有很多开发者在继续使用VC6,这些开发者也不得不“感激”Visual C++团队在那个版本里做出忽略大量与标准的兼容性的决定。(比如,对那些开发者来说,如果内存用尽,new不会抛异常,而是返回一个空指针。)

 

- The Standard Template Library,HP原作,1993-今。虽然仅仅考虑到标准模板库对C++贡献颇多,也能将其选到列表里,但是像C++这种语言,其标准库中提供一套容器和算法,这本身没什么好惊奇的。但是,STL的贡献要比仅仅作为一套基础库,要大的多。STL还实践了一套架构,这个架构可以让容器和算法的设计和运作完全分离,仅仅依靠迭代器将两者联系起来。并且还演示了如何将数组和指针封装为容器和迭代器,因此很大程度上消除了语言特性和库之间的鸿沟。并且,它还演示了如何由用户扩展库,可以引入新容器,新算法,和新的迭代器类型,而且每种新的东西都可以像STL固有的那样,与STL的其他组件协同工作。并且,它还解释了为什么不需要区分容器和容器的附属区域。并且,它的效率非常高,避开了传统的基于继承的面向对象的方案,仅仅依靠模版实现了这些功能。它在C++社区引入了泛型编程。这最终导致我们在设计库和库框架时,不再使用原来的方法,但是人们依旧可以简单的使用类型T的容器。我在Effective STL中写到:“在我近30年的编程生涯中,我从没看到有什么东西能像STL一样(优雅?成功?这里指前面的介绍……)”现在已经超过30年了,但我仍然坚持我的看法。

 

- The Libraris at Boost,1999-今。这个选择有点欺骗的味道,因为Boost并不是一个库,而是一个保护组织,其目的是收集各种库的设计,并让众多的人以不同的感觉和设计目标来实现库。其结果就是,Boost库提供的功能和他们的前景一样,毫无目的。尽管这样,Boost及其库,对C++来说依然非常重要,而且看起来其影响会越来越大。在TR1中定义的14个新功能里(其中有13个已经进入了C++ 0x的草案),有10个(注4)是基于Boost库的经验而提出来的。没有哪个组织,能像Boost一样,对未来C++扩展库的功能有如此大的影响。

 

Boost在这方面有如此重大的影响,并非出于偶然。组建Boost的目的就是作为了测试和推广将来可能最终加入到C++的库。TR1的绝大部分工作是基于Boost,这证明了这个组织的成功,并且,看起来TR2仍将包含大量的基于Boost的功能。

 

如果你google “C++ libraries”(不加引号),你将会发现Boost在第一位。如果说人么想起库就想起Boost,这个说法还有争议的话,但是Boost确实越来越和C++库紧密关联起来了。

 

现在,软件工具对C++的成功是非常重要的,但是,最终,所有的东西都要归结到人。这对于C++,和其他由人完成的东西,都是一样的。在我这个系列文章的下个部分里,我将告诉你我认为的最重要的人——C++世界中的泰坦们。(注5)

 

注解:

1 对于“解析”,我的意思不仅仅是建一棵抽象语法树。我也指要完成隐式模版实例化,判定重载函数的调用,等等。我合并了语法和语意解析,但是很多功能强大的C++工具的入口就是语意解析,并且,按照通常的说法,人们把这整个的过程称作“解析”。

 

2 由于社区太大了,而且变化很快,因此很难准确说出“大部分程序员”的行为。

 

3 “Unix的语言”是Java。我不知道Apple的语言是什么。

 

4 这10个组件(既有TR1的术语,也有我自己起的名字)是reference wrappers(对引用的封装), smart pointers(智能指针), enhanced member pointer adapters (mem_fn)(增强的成员函数适配器), enhanced binders (bind)(增强的绑定), generalized Functors (function)(泛化仿函数), type traits(类型特征,貌似也有叫垫片的), random numbers(随机数), tuples(元组。元祖?), fixed-size arrays(定容量数组), 和regular expressions(正则表达式)。

 

5 所有人都认为泰坦很强,除了我那个作为一流学者的妻子。她总是提醒我虽然泰坦很强,但是他们那种强壮依靠肌肉,而不是大脑。这就是为什么他们在和奥林匹克诸神(宙斯家族)的斗争中总是处于下风。还是由你来决定他们是否和C++类似吧,并且,如果真的是这样的话,那么谁,或者什么事物,扮演了奥林匹克诸神的角色呢?

  评论这张
 
阅读(492)| 评论(1)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017