作者介绍
Scott Meyers
,
C++
顶级权威之一,为世界各地客户提供培训和咨询服务。出版有畅销的
Effective C++
系列图书(《
Effective C++
》、《
More Effective C++
》和《
Effective STL
》),设计了创新型的
Effective C++ CD
,
Addison Wesley
的
Effective Software Development Series
顾问编辑,
The C++ Source (http://www.artima.com/cppsource/)
咨询板块专家。布朗大学计算机科学博士,他的网站是
www.aristeia.com
。
在本系列的第三篇文章里,我将把视线转移到评选过去最重要的
C++
软件上来。
用
C++
编写软件,你需要工具的帮助。在我看来,这些工具曾经是(将来也是)有关
C++
的最重要软件。可以想见,曾经出现了不少用
C++
开发的重磅软件,它们促使很多人为了以后项目的开发选择了这门语言,但我不关心这些。这门语言最重要的软件应该是软件开发人群使用的最基本的东西:编译器和库。可能,
C++
是更为库编写而不是应用开发所设计的一门语言。
我选择的
C++
历史上最重要的五个软件如下,以诞生年份为序:
Cfront
,
AT&T
的
Bell
实验室
开发,
1985-1993
。
Cfront
是最早的
C++
编译器。它可是真正的编译器,不过生成的是
C
格式的目标码。因此将它认作
C++
到
C
代码的预处理器是很自然的。很难让人在调试时不做它想,因为至少在我
1998
年开始使用它时,仍然没有
C++
调试器。头发花白的前辈们当时使用
C
调试器,必须要对付那些让人精神崩溃的名字(比如,识别调试器里指向
C++
源代码中某个加法函数的
__pl__1Aff
)。
事实上,
Cfront
生成
C
目标码有两个好处。第一,可以非常容易将
Cfront
移植到新的平台,因为
C
编译器到处都是。这就促成了
C++
在各种环境里的快速传播。第二,使用者可以观察编译生成的代码,知道编译所做的工作。当大多数人还是
C++
新手的时候,通过揭示其工作过程,有助于消除大家对
C++
的神秘感。它也扮演某种保护伞的角色。不用担心
C++
用黑纱蒙住你的眼睛,因为它所做的任何事情都清清楚楚摆在那里(至少和从前机器生成的
C
代码一样清楚)。
在
1990
年前,
Cfront
不仅是个编译器,而且也成了事实上的语言标准。
C++
诞生于
AT&T
,
Cfront
来自
AT&T
的
C++
小组,因此无论
Cfront
干什么,自然是不会错的。长期以来,其他厂商的编译器紧跟
Cfront
,以致
Cfront
的
bug
都被原样复制。直到《
Annotated C++ Reference Manual
》(
ARM
)发布,
Cfront
的标准色彩才逐渐消退,特别是大家认识到要为
Cfront
加入异常处理机制需要付出巨大努力的时候。
Cfront
的最后版本发布于
1993
年,但阴魂不散。
Edison Design Group
,一家专业生产最贴近
C++
标准的
front-end
编译器的商业公司,在
2006
年
7
月的文件里还指出它们的编译器兼容
Cfront
模式。我猜测仍然
Cfront
仍然在一些不支持本地
C++
编译器的嵌入式项目中发挥作用,当然仅仅是猜测。
GCC
,
GNU
工程
的杰作,
1987
至今。
GNU
很早就进入了
C++
商业领域,并且发布了第一个生成本地代码的编译器(相对
Cfront
的
C++-C
转换而言)。多年以来,
GNU
编译器成了跨平台应用开发的不二选择。事实上,它是一个交叉编译器,这也使它在嵌入式系统开发领域广受欢迎。
GCC
本身是一个支持多种
front-end
(包括
C
、
C++
和
FORTRAN
等)和针对各种平台的
back-end
工具的编译器平台,其
C++
版本就是广为人之的
g++
。
g++
的早期推动人是
Michael Tiemann
。我不由得回忆起自己曾经提交了一份
g++
的
bug
报告,很快就得到了
Tiemann
的回应。他提供了新的
g++
文法,并请我据此重建编译器,看看我报告的问题是否解决了。我记得问题依然存在,但一个编译器的作者特意送你一个修改补丁并请安装试用,已经难能可贵了。顺便提及一下,
Tiemann
于
1989
年与人合伙创办了
Cygnus Support
,我相信
Cygnus
是历史上第一个提供免费软件的公司。据说早期的时候,
Tiemann
有时会躺在浴盆里召开
Cygnus
的会议。
g++
是开源的,这样
C++
社区就可免费获得与
C++
标准一致的
front-end
工具。但我从未听说哪个以
g++
代码为基础编写的开源工具(如
Lint
、重构工具等等)的解析能力能与
g++
比肩。有不少可以解析所有
C++
声明的工具(比如
gccxml
),但据我所知,没有哪个工具能同时解析声明和定义部分(特别是函数体)。因此尽管我于它没有个人使用经历,但我怀疑
g++
的
front-end
是否在完全开源上有所保留。这对于
C++
开发者来说是不幸的,因为尽管有很多工具可供使用,但其真正威力应该是解析
[
注释
1]
C++
源代码的能力,这是一个难以逾越的障碍。
Visual C++
,
Microsoft
出品,
1992
至今。
VC++
是
C++
成功的最大推动力之一,也是延缓
C++
进步的最大障碍之一。尽管
Bjarne Stroustrup
断言“没有人知道大多数
C++
开发者到底在干什么”
[
注释
2]
,但我基本上不会怀疑如果我将这颗星球上所有
C++
开发者召集到一起,并要求为他们使用的编译器投票,我想大多数人都会提到
VC++
。仅就这点而言,
VC++
已经并将继续对
C++
产生重要影响。而且,
Microsoft
的旗舰产品(如操作系统、
Office
等)也完全或主要用
C++
编写,并用
VC++
编译。这也加重了
VC++
在
C++
世界的分量。该公司对
C++
的倚重促使它开发了很多工具和
API
来支持其应用,从而导致很多
Windows
开发人员也使用这门语言。到了
90
年代晚期,很多人(这让我震惊甚至恐惧)将
C++
叫做“
Microsoft
语言”
[
注释
3]
。
VC++
在
C++
领域占据了统治地位。对于大多数程序员而言,
Visual C++
就是
C++
。
不幸的是在
Microsoft
的
C++
实现里,标准的缺失持续了很多年。
1998
年前,这算不上一个问题,因为根本就不存在可以遵从的标准,其他编译器厂商也是各行其道。然而,
VC6
于
1998
年发布,此时距
C++
标准完成已近一年。与同类产品相比,
VC6
与
C++
标准差得最远。当然这在当时仍然不是一个十分的严重问题,因为很少有程序员马上使用
C++
标准里的最新特性。糟糕的是
VC6
一直维持到
2002
年(
VC7
发布),甚至
VC7
编译器本身也没有大的改变。在这些年里,对标准的支持,基本上都是以更新库(如
STL
)的形式实现,而我们很多人都觉得多年前就应该发布升级版本。
2003
年的
VC7.1
终于解决了大部分标准兼容问题,但在
VC6
至
VC7.1
的六年间,使用
VC6
的跨平台开发者必须因其缺陷付出艰苦努力,最典型的就是通过条件编译(也就意味着代码零乱)解决模板偏特化等问题。不过,很多开发者直到今天仍在使用
VC6
,他们也得继续感谢
VC6
小组大范围忽视标准兼容的决定。比如,新的版本在内存耗尽时不抛出异常,而直接返回空指针。
2003
年后,
VC++
不再存在我认为相当严重的标准兼容性问题,我相信它现在的领导者非常重视标准兼容。然而,我在
1998
到
2003
这六年来经常接触的都是工作(至少就编程序而言)中并无特别困难的开发者,因此我理直气壮地决定将我对
Microsoft
的“警惕”保持到
2008
年——从他们发布一个“真正的”
C++
编译器起的六年。
The Standard Template Library
,源自
HP
,
1993
年至今。像
C++
这类语言的标准库应该提供一系列常用容器和算法,这个说法并不会让人格外惊讶,但即便这样的作品也可能上这个榜。而
STL
对
C++
的贡献远非如此。它引入了容器和算法的设计架构,这样,仅仅通过迭代器交互就能实现无缝协作。它示范了如何用容器和迭代器替代数组和指针。此外,它还告诉用户如何扩展架构,允许引入新的容器、算法和迭代类型——它们可以像
STL
自有组件那样和任何符合
STL
标准的组件一起工作。所有这些都以效率为实现基础,不考虑经典的面向对象、基于继承的解决方案,而几乎完全依赖于模板技术。它还为
C++
引入了泛型编程。这一切的努力给我们带来了库和库框架设计思路上的转变,也满足了那些寻找便利的、可移植容器者的需求。我在《
Effective STL
》(
Addison-Wesley, 2001
)里写到,“我已经编程三十年,但我从未发现
STL
的比肩者”。现在已经超过了
30
年,我仍然没有发现。
Boost
类库
,诞生于
1999
年。这项选择似乎带点儿欺骗,因为
Boost
实际上不是一个类库,而是一个收容人们因各种目的和想法而设计实现的一系列库的组织。因此,
Boost
库在提供什么以及如何提供功能上似乎漫无目的。然而,
Boost
及其库对
C++
产生了重大影响,这种影响在未来可能更为明显。
TR1
中规定的
14
类新功能(其中
13
个已经写入
C++0x
草案)里,有
10
个
[
注释
4]
来源于
Boost
库使用者的建议。
Boost
的影响并非偶然。它就是以充当那些可能最终被加入
C++
标准的库的实验床和推动者为目的而创立的。
TR1
对
Boost
的重视已经证明了它的成功,而且
TR2
很可能包纳
Boost
中更多功能。
如果在
Google
中搜索“
C++ libraries
”(不带引号),你会发现
Boost
排在头条。这是否意味着人们想到
C++
库,就会想到
Boost
呢?我想它至少说明了
Boost
与
C++
库的关系是多么密切吧。
当前,软件工具已经成为
C++
成功的关键因素,但归根结底,任何美好的东西都要人来创造。
C++
是如此,人类任何别的劳动也是如此。在下篇系列文章里,我将告诉你我认为谁是最重要的人——
C++
世界的巨人
[
注释
5]
。
注释:
1.
所谓“解析”,我指的不仅仅是构建抽象语法树,还包括执行隐式模板实例化、解析重载函数调用等。也就是说包括解析和语义分析,不过很多
C++
工具的威力起点是语义分析的结果。人们常常将这整个过程叫做“解析”。
2.C++
社区是如此庞大和复杂,以至于无法分析“大多数程序员”的行为。
3.
“
Unix
语言”是
Java
,我不知道
Apple
语言应该是什么。
4.
它们是:
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++
世界里是否存在同样现象的问题留给你们,如果有,那么是谁或者说是什么扮演着奥运会选手的角色呢?
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1480575