2007年9月14日星期五

Doctor Bjarne.Stroustrup

C++ 之父 B.Stroustrup言论(译者:孟岩,来自侯捷老师主页)节选,转载至此作为备份

以下蓝色为提问,黑色为回答。红色 为译注,紫色为侯捷个人认为宜再斟酌之处。
浅蓝色
是侯捷个人阅读时的神秘标记。

1. 我如何开始学习C++?

这取决于你的基础和学习动机。如果你是个初学者,我想你最好找个有经验的程序员来帮助你,要不然你在学习和实践中不 可避免的犯下的种种错误会大大地打击你的积极性。另外,即使你的编译器配备了充足的文档资料,一本C++书籍也永远是必不可少的,毕竟文档资料不是学习编 程思想的好教材。

选择书籍时,务必注意该书是不是从一开始就讲授标准C++并且矢志不渝地使用标准库机制。例如,从输入中读取一个字符串应该是这样的:

    string s;    // Standard C++ style
    cin >> s;

而不是这样的:

    char s[MAX];    /* Standard C style */
    scanf("%s",s);

去看看那些扎实的C++程序员们推荐的书吧。记住,没有哪本书对所有人来说都是最好的。另外,要写地道的C++程序,而避免用C++的语法写传统风格的程序,新瓶装旧酒没多大意义。(遗憾的是,目前在市面上的中文C++教材中,符合B. S的这个标准的可以说一本都没有,大家只好到网上找一些英文的资料来学习了。--译者)


2. 怎样改进我的C++程序?

不好说。这取决于你是怎麽使用该语言的。大多数人低估了抽象类和模板的价值,反过来却肆无忌惮地使用造型机制(cast)和宏。这方面可以看看我的文章和书。抽象类和和模板的作用当然是提供一种方便的手段建构单根的类层次或者重用函数,但更重要的是,它们作为接口提供了简洁的 逻辑性的服务表示机制。

3. 如果不必和C兼容,你所创造的语言是不是就会是Java?

不是,差得远。如果人们非要拿C++和Java来作比较,我建议他们去阅读The Design and Evolution of C++,看看C++为什麽是今天这个样子,用我在设计C++时遵从的原则来检验这两种语言。这些原则与SUN的Java开发小组所持的理念显然是不同的。 除了表面语法的相似性之外,C++与Java是截然不同的语言。在很多方面,Java更像Smalltalk(译者按:我学习Java时用的是Sun的培训教材,里面清楚地写道:Java在设计上采用了与C++相似的语法,与Smalltalk相似的语义。所以可以说Java与C++是貌合神离,与Smalltalk才是心有灵犀)。Java语言相对简单,这部分是一种错觉,部份是因为这种语言还不完整。 随 时间的推移,Java在体积和复杂程度上都会大大增长。在体积上它会增长两到三倍,而且会出现一些实现相关的扩展或者库。这是一条每个成功的商业语言都必须走过的发展之路。随便分析一种你认为在很大范围内取得了成功的语言,我知道肯定是无有例外者,而且实际上这非常有道理。

上边这段话是在Java 1.1推出之前写的。我确信Java需要类似模板的机制,并且需要增强对於固有类型的支持。 简单地说,就是为了基本的完整性也应该做这些工作。另外还需要做很多小的改动,大部份是扩展。1998年秋,我从James Gosling(Java语言的创始人--译者)那 里得到一份建议书,说是要在Java中增加固有类型 操作符重载以及数学计算支持。还有一篇论文,是数学分析领域的世界级大师,伯克利大学的W. Kahan教授所写的How Java's Floating-Point Hurts Everyone Everywhere("且看Java的浮点运算如何危害了普天下的芸芸众生"--译者),揭露了Java的一些秘密。

我 发现在电视和出版物中关於Java的鼓吹是不准确的,而且气势汹汹,让人讨厌。大肆叫嚣凡是非Java的代码都是垃圾,这是对程序员的侮辱;建议把所有的 保留代码都用Java重写,这是丧心病狂,既不现实也不负责任。Sun和他的追随者似乎觉得为了对付微软罪恶的"帝国时代",就必须如此自吹自擂。但是侮 辱和欺诈只会把那些喜欢使用不同编程语言的程序员逼到微软阵营里去。

Java并非平台无关,它本身就是平台。跟Windows一样,它也是一个专有的商业平台。也就是说,你可以为Windows/Intel编写代码,也可以为Java/JVM编写代码,在任何一种情况下,你都是在为一个属於某个公司的平台写代码,这些代码都是与该公司的商业利益扯在一起的。 当然你可以使用任何一种语言,结合操作系统的机制来编写可供JVM执行的程序,但是JVM之类的东西是强烈地偏向于Java语言的。它一点也不像是通用的 公平的 语言中立的VM/OS。

私下里,我会坚持使用可移植的C++作大部份工作,用不同的语言作余下的工作。
("Java is not platform-independent, it is the platform",B. S的这句评语对於C++用户有 很大的影响,译者在国外的几个新闻组里看到,有些C++高手甚至把这句话作为自己的签名档,以表明对Java的态度和誓死捍卫C++的决心。实际上有很多 程序员不光是把自己喜爱的语言当成一种工具,更当成一种信仰。--译者)

4. 您怎麽看待C#语言?

就C#语言本身我没什麽好说的。想让我相信这个世界还需要另外一个专有的语言可不是一件容易的事,而且这个语言还是专门针对某一个专有操作系统的,这就更让我难以接受。直截了当地说,我不是一个专有语言的痴迷者,而是一个开放的正式标准的拥护者。


5. 在做小项目时,C优于C++吗?

我认为非也。除了由於缺乏好的C++编译器而导致的问题之外,我从没有看到哪个项目用C会比用C++更合适。(不过现在C++编译器导致的问题还是不可忽略的,当你看到同样功能的C++程序可执行代码体积比C大一倍而且速度慢得多时,会对此有所感触的。--译者)


6. 您预期C++做哪些增强,会不会删掉一些东西?

很不幸,虽然有一些东西很应该扔掉,但恐怕很难真的删掉任何东西。第一个应该抛弃的东西就是C风格的造型机制和类型截断转换。就算不禁止,编译器的作者们至少也应该对这种行为给与强烈的警告。我希望能用类似vector的东西彻底取代数组,但这显然是不可能的。不过如果程序员们能主动使用vector来代替数组,就会立刻受益匪浅。关键是你不必再使用C++中最复杂难缠的技巧了,现在有优秀得多的替代方案。

至於主要的特性,我没想去掉任何东西。特别是那些把C++与C区别开来的主要特性恐怕没法风平浪静的被抛掉。通常问这些问题的人是希望我挑出诸如多继承 异常 模板等机制来接受批判。所以在这我想大声讲清楚,我认为多继承机制对於静态类型语言实现继承性来说是必需的,异常机制是在大系统中对付错误的正确方法,模板机制是进行类型安全的 精致的和高效的程序设计的灵丹妙药 。我们可以在小的细节上对於这些机制挑挑刺,但在大的方面,这些基本的概念都必须坚持。
现在我们仍在学习标准C++,也正在标准所提供的特性基础上发展出更新的 更有趣的编程技术。特别是人们刚刚开始使用STL和异常机制,还有很多高效强大的技术鲜为人知,所以大可不必急匆匆的跑去增加什麽新的机制。

我认为当前的重点是提供很多新的 比以前更加精致的 更有用的库,这方面潜力巨大。例如,如果有一个能被广泛使用的 更精致的支持 并发程序设计的库,那将是一大福音--C风格的线程库(例如Pthread--译者)实在不够好。我们也就可以与各种其他的系统,例如SQL以及不同的组件模型更好地契合起来。数值计算领域的人们在这方面好像已经走在了前面,类似像Blitz++ POOMA MTL之类的高效而精致的库的开发已经取得了非凡的成就。 (译 者在Internet上造访了Blitz++和POOMA的主页,前者是一个高性能数学库,据称其性能与Fortran 77不相上下,同时又支持大量的C++特性。我想凡是对於数值计算领域有所了解的人都知道这有多麽伟大的意义。POOMA则是一个专门研究C++并行数学 算法的项目,它的前景更加不可限量。译者非常认同B. S的这个观念。--译者)

有了足够的经验之後,我们就能更好的决定应该对标准做些什麽调整。


7. 有没有计划往标准C++里增加一些新的特性以支持分布式计算?

没有,我也不认为有这个必要。用更好的库就差不多能解决问题了。最多,为了支持这类的库,我们可能会增加一些低级的原操作和规则

8. 未来C++有没有可能定一个可移植的二进制接口?

如果你说的"可移植"是指跨硬件和块操作系统的可移植,我想回答是不会。我们当然可以设计一个解释器或者虚拟机(如同Java的做法--译者),但这样一来,由於无法以最优的方式访问系统资源,C++的能力就会受到削弱,。我真正希望在不远的将来能够看见的东西是platform ABIs (ABI, Application Binary Interface) 。例如,有人正在努力为Intel新的IA64体系定义C++ ABI,我想这些努力会得到用户们的巨大支持。能够把不同编译器产生的代码编译在一起将会是一项十分有意义的事情。

9. 在不少流行领域,C++正在渐渐失去光芒,因为它要求人们花很大的精力去对付一些很基本的工作,比如管理内存(因为没有垃圾收集机制),管理模块之间的依 赖性(因为没有包机制),管理组件的版本。C++缺乏一些现代语言已经视为标准的特性。比如传言中最酷的Java语言就特别重视这些问题。那麽在解决这些 问题是否会导致C++的发展背离其根本宗旨呢?C++应该怎样发展以保证我们在这种语言上的投资能有合理的回报,而不是被迫去重新使用另一种语言?

我倒还没有注意到C++比以前用的少了。相反,我看到的指标表明C+的使用还在稳定地增长 。只不过这种基数很大的稳定增长以及在标准性 移植性和库方面的不断提高并没有造成什麽具有欺骗性的新闻效应而已。我认为你所说的"失去光芒"只不过是市场推销和新闻意义上的现象。

如果你需要垃圾收集机制的话,你可以在C++应用程序中插入一个垃圾收集器。有不少自由的和商业的垃圾收集器已经在重要的实践中被证明是很出色的。

如果你不想使用垃圾收集机制,也没关系。你可以使用标准容器类,它们大大减少了对於显式分配和回收内存的需要。这样,使用现代的库和现代的编程风格,你能够避免大部份的内存管理问题。

同样的技术还能够用来避免一般资源的管理问题。并不是只有内存才会泄漏,线程句柄 文件 互斥锁 网络连接等都是重要的资源,为了建立可靠的系统,这些资源必须被正确的管理。 如果你觉得有了垃圾收集机制就可以解决所有的资源管理问题,那麽你最好赶快从美梦中醒来。

C++提供了很多机制来管理一般性的资源。关键的手段--"Resource Acquisition is Initialization"(这是著名的RAII惯用法,阅读原文时会经常遇到,其意义是说将所有的资源分配申请放在对象初始化过程中进行,而将资源释放动作放在对象销毁过程中――译者) 可以使用函数对象来管理生存期问题。语言中关於对象的局部构造和异常机制对这项技术提供了支持。

某些语言的狂热支持者总是用讽刺漫画的笔法描述C++,然而C++实际上要好得多。特别是我觉得很多其他的特性已经泛滥不堪了,在C++中,通常这些特性能够很容易的被模拟出来。相反的,新的语言在推广的过程中总是不断地增加新的特性,这就是为什麽从一种语言诞生到被广泛使用,其体积通常会增加个两三倍。

目前,最为个人和组织,对於C++的最好投资就是去更好地理解标准C++和现代的C++设计编程技术。大多数人使用C++的方式实际上停留80年代中期的水平,甚至比那更陈旧。

至於模块依赖性问题,我的观点是,在编程语言的工作和系统的工作之间应该有一个明显的界线,依赖关系应该尽可能地与编程语言分开,而由系统来支持。

我不认为组建版本的问题应该由编程语言来解决,这是一个系统范畴里的问题,在语言里应该通过提供相应的库来解决。C++有这样的机制。

解决这样的问题不会使C++偏离轨道。但是给C++增加很多特殊的特性就会使C++偏离轨道,而且在保持可移植性和平台独立性方面也会是一个倒退。

10. 标准C++推出有段时间了,Java也大踏步地往前走而且取得了显着的进步,您现在怎麽比较Java与C++?您觉得Java想要变成像C++一样"好" 的语言还需要做些什麽?您举的C++从Java身上学到了什麽经验吗?有没有什麽Java的特性您认为是可以被C++吸纳的?

我不比较语言。做好这项工作是十分困难的,而且很少具有专业水准。

我认为C++的进步会是主要以它的用户在使用中遇到的问题以及其自身逻辑为基础。当然,其他语言中的某些思想也会被考虑,但不能被简单的移花接木过来。你必须审视那些机制在技术上和思想上的背景,并且找到在C++中支持这些技术的最佳方案。

有 时最好的选择是综合使用几种语言。毕竟没有任何一种语言是放之四海而皆优的。C++现在是,将来也继续会是在广泛应用领域中最好的语言之一。但是,我们不 能被拉下水,不能把所有可能的特性都加到C++里面来向大众献媚。我认为Java和C++现在和将来都会是十分不同的语言,语法相似,但背後的对象模型明 显不同。

对於我来说,一个很重要的区别是C++有一个ISO标准,而Java则是一个专有语言。

11. 在Java刚刚出现的那几年,有很多欺骗性的言论说它将会是终极语言,会取代C++。您觉得在过去两三年里Java对C++的追随者们有什麽影响?

到现在关於Java的不实之辞也还随处可见。暂且不提Java在过去5年间的创纪录的发展,狂热的大众似乎认为 Java将最终取代的不仅仅是C++,而且还有所有其他的编程语言。但在另一方面,C++的使用仍在继续增长。我不认为Java对於C++的影响已经使得 人们转而把本来打算用来创造更好的C++工具库的资源调过去开发Java工具库。Java对於学习编程的人来说没有太多的新东西,所以对於C++的定义也 没什麽影响。在那个领域,Java还得努力追赶。例如,我认为为Sun迟早会往Java里加入类似模板的机制

人们应该认识到C++和Java的目标是何等的不同。 以C++的设计理念来衡量Java,或是以Java的设计理念来衡量C++,得出的结论都不会很好。

在访谈即将结束时,或许我该再次表明态度:C++仍然是我喜爱的语言,在写代码时你会发现没有那种语言能像它那样在如此广泛的应用领域和平台上同时达成如此的高效与精致。