大龙的博客

常用链接

统计

最新评论

[转载]专访Bjarne Stroustrup

荣耀,马皓明译....
Elden Nelson:如果您现在有机会从头设计C++语言,您会做些什么样的改变?

Bjarne Stroustrup:当然,你永远都不可能重新设计一种语言,那没有意义,而且任何一种语言都是它那个时代的产物。如果让我今天再设计一种语言,我仍然会综合考虑逻辑的优美、效率、通用性、实现的复杂程度以及人们的喜好。要知道人们的习惯对于其喜好有着巨大的影响。

现在,我会寻找一种简单得多的语法 ?它可能与人们对?#29087;悉?#21644;?#31616;单?#30340;混淆认识相悖,我会把对类型系统的侵犯限制在极少的语言构造里,并且用明显?#19985;陋?#30340;语法来标识它们。(就象我对对新风格的?#36716;型?#30340;处理,比方说,reinterpret_cast<int>(p)就是一个用来描述一种?#19985;陋?#25805;作的?#19985;陋?#35760;号)。这样可以很容易地禁止不安全的操作。

我还会把核心语言的体积搞得尽可能小一些,包括类和模板的关键的抽象特性,而把很多其它的语言功能放在库里来解决。当然我也会保证核心语言足够强大,使得那些库本身也足以用此核心语言来产生。我可不希望标准库的编写者依赖于普通用户无法使用的额外的语言特性。我还努力使核心语言的定义更加精确。

最重要的是,我会在该语言被广泛使用之前尽可能维持一个很长的酝酿期,这样我就可以根据来自真实用户的坚实反馈对它进行改进。这可能是最困难的,因为一旦有什么东西明显出色并且前途光明,它就会被广为使用,此后进行任何不兼容的修正都将变得极其困难。

我相信这些思想与我当初设计C++时的理念是非常类似的,它们同样也指引着一、二十年来C++的不断演化。当然,我认为现在还没有什么东西能让我觉得象是?#23436;美的语言?#12290;

Elden Nelson:当您设计C++语言时,您是否借鉴了其他崭露头角的对象语言(例如Modula-2)的思想?

Bjarne Stroustrup:在C++的设计过程中,我吸取了C、BCPL、SIMULA、ALGOL 68、Ada、ML以及其他一些语言的思想。当时我知道Modula-2,还知道至少一打别的语言,但我回想不起来Modula-2对我产生了什么直接的影响。

为了回答?#20026;什么C++会是这样(以及为什么不这样)?#20043;类的问题,我撰写了《The Design and Evolution of C++》一书。也就是说,这本书记录了导致C++现状的设计决策、原则以及折中权衡,我推荐对此类问题感兴趣的读者阅读这本书。

Elden Nelson:您预期对C++做哪些增强,会不会删掉一些东西?

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

我没打算去掉任何大的特性。特别是那些把C++与C区别开来的主要特性恐怕没法风平浪静地被抛掉。通常问这些问题的人是希望我挑出诸如多继承、异常、模板等机制来接受批判。所以在此我想大声讲清楚,我认为多继承机制对于一门具有继承机制的静态类型语言来说是必需的,异常机制是在大系统中对付错误的恰当的方法,模板机制对于类型安全、优雅和高效的程序设计来说不可或缺。我们可以在语言细节方面对这些机制吹毛求疵,但在大的方面,这些基本概念都必须坚持。

现在我们仍在学习标准C++,也正在标准所提供的特性基础上发展出更新且更有意思的编程技术。特别是人们刚刚开始使用STL和异常机制,还有很多高效强大的技术鲜为人知,所以大可不必急匆匆地跑去增加什么新机制。

我认为当前的重点是提供很多新的、比以前更加精致的且更有用的库,这方面潜力巨大。例如,如果有一个能被广泛使用的、更精致的支持并发程序设计的库,那将是一大福音 ?C风格的线程库实在不理想。我们也就可以与各种其他的系统比如SQL以及不同的组件模型更好地契合起来。在优雅高效的库的开发方面,数值计算领域的人们看起来已经走到了前面(例如Blitz++、POOMA和MTL,请访问www.research.att.com/~bs/C++.html)。

有了足够的经验之后,我们就可以更好地决定什么能够(也应该)被标准化。

Elden Nelson:我们正不可避免地走向一个以Web为中心、分布式计算为主流的时代。那么您觉得C++还能维持其地位吗?程序员们可不可能把若干种专用语言(比如Perl、Javascript)综合运用以彻底取代某一种通用语言?为了配合新的计算模式,C++或标准库应该做出怎样的调整?

Bjarne Stroustrup:从来没有哪一种语言能适合所有的工作,恐怕以后也不会有。实际系统通常是用多种语言和工具构造起来的。C++只是想成为若干语言和工具中的一个,当某些专用语言在其领域里特别突出时,它们可以与C++互为补充。也就是说,我觉得如果大多数现在的专用语言能借助特定领域的C++库共同工作的话,它们会表现得更出色,而脚本语言通常导致难以维护的代码,这或许跟语言选择关系不大,可能更是因为急着想将产品尽快推向市场。如此一来,哪还有什么精力考虑程序结构、伸缩性和可维护性方面的问题?

我不敢肯定未来的代码是否真的会以Web为中心,就算是直接处理Web的系统也主要是由处理本地资源(比如IP连接)的程序模块构成的。

地理上的分布性以及服务器软件对于并发机制的高度依赖对于系统的构建者来说的确是个挑战。针对上述问题的一些库已经出现,也许我们将会看到它们最终得以标准化。当然,一些原语操作(primitive operations)和保证规则应该被加到核心语言中以提供对这些库的更佳支持。

总的来说,对于Web和网络,我们非常需要一个真正的系统/网络级的安全模型。指望下载的?#20197;JavaScript之类的语言编写?#30340;脚本来实现这个模型无异于痴人说梦。请注意,我也并没有宣称C++提供了这个问题的解决方案。C++被设计为对所有系统资源提供高效的访问,而不是为了防止被欺骗。

Elden Nelson:您认为C++未来的走向如何?在接下来的10年里它会衰落吗?或者基本保持现状,或者演化为某种不一样的东西?

Bjarne Stroustrup:C++有着极美好的未来。用它你能写出伟大的代码。不管被多少敌意的宣传所攻击,C++仍将是开发高性能、高复杂度系统的最佳语言。据我所知,还没有哪种语言能象C++这样,将通用性、效率和优雅有机结合。

我没看到C++有衰落的迹象。在我能预见的未来里,它的用途还会不断增长。当然,在未来的十年里我们会看到一些变化,但不会象这篇访谈中的这套问题所暗示的那么多。跟每一种语言一样,C++也会不断演化。?#35821;言专家们?#35201;求改进的喧嚣声震耳欲聋,但是系统开发者们的基本请求是保持稳定。

C++会改进,但这些改进将是?#32463;验?#30340;结果而非对?#29378;热?#30340;反应。为了更高效地使用一些新的编程技术,比如通用编程技术,可能会增加一些小特性。会有大量的库涌现,我预期会出现一些新颖的便利设施以支持更好的库。我希望新的扩展主要集中在支持抽象方面的一般特性,而不是为支持某些特殊任务的特定机制。

打个比方,属性(properties)是一个有用的应用层的概念,但我不认为在一种通用编程语言中有它的容身之地。用标准C++的一组类可以很容易地支持这一概念。如果我们感觉那族类对于?#23646;性?#36825;一概念的支持不合口味,我们也不应该立刻跑去在语言里增加属性机制,而是仔细考虑如何改进类和模板以帮助库设计人员尽可能接近?#23646;性?#36825;个概念。也许通过改进函数对象(function objects)机制能够给这个问题一个满意的答复。

为了使C++在接下来的十几年中保持生命力,很基本的一点就是不要让标准C++赶什么学术或商业时髦。人们要求增加的特性中很大一部份通过使用现有的标准C++开发新库的方式都可以实现。还有,事实上人们渴望得到的很多奇妙的特性已经包含于标准C++之中,并且被所有最新版本的编译器所支持。对许多程序员来说,提高代码质量的最佳途径不是追求什么语言扩展,而是静下心来品味最新的C++技术书籍。

Elden Nelson:对于当前脚本语言的兴旺态势您怎么看?特别是Python,与C++相比,它似乎提供了一种更简单的OO技术学习途径。

Bjarne Stroustrup:有些语言很不错。比如Python,我很喜欢。但是我认为你从不同的语言中学到的OO技术是不完全相同的。当然,每一个职业程序员都要通晓几门语言,并且应该意识到,在不同的语言之中,编程和设计技术有着显著不同。

在我看来,用脚本语言建造的系统与用C++那样的通用语言建造的系统大不相同。从两类语言中学到的技术区别明显。不存在?#21487;以满足绝大多数高效系统构建所需?#30340;公共OO技术子集。

Elden Nelson:有没有计划对标准C++语言进行扩充或改进,从而为分布式计算提供更好的支持?

Bjarne Stroustrup:没有,我也不认为有这个必要。用更好的库就差不多能解决问题了。充其量为了支持这类的库,我们可能会增加一些低级的?#21407;操作(primitives)?#25110;?#20445;证(guarantees)?#12290;

Elden Nelson:将来C++有没有可能定义一个可移植的二进制接口?

Bjarne Stroustrup:如果你说的?#21487;移植?#26159;指跨硬件和跨操作系统,我想答案是no。我们当然可以设计一个解释器或者虚拟机什么的,但这样一来,由于无法以最优方式访问系统资源,C++的能力就会受到削弱。我希望在不远的将来能够看见平台ABIs(platform ABIs)。例如,有人正在努力为Intel新的IA64架构定义C++ ABI(参见http://reality.sgi.com/dehnert_engr/cxx,http://developer.intel.com/design/ia-64/devinfo.htm),我想这些努力会得到用户社群的强烈支持。

能够把一台PC上不同编译器产生的代码连接(link)在一起是一件美妙的事。

Elden Nelson:您目前是否正在为其他新语言开展工作?

Bjarne Stroustrup:没有。我还在学习如何使用标准C++,并且进行一些分布式计算的试验。我认为编程本身远比编程语言细节有趣。我认为只有当你有一些东西无法用已有语言合理表达时,才需要考虑设计一门新语言。对我来说,绝大部分工作都可以通过C++很好地完成。

Elden Nelson:以?#21518;知之明?#30340;角度来看,您是否认为?#20351;一个成员函数默认为非虚函数?#26159;一个明智的决定?假设有机会改变,您会改变这个决定吗?

Bjarne Stroustrup:也是也不是。

使C++保持生命力的要素之一即是?#38646;开销规则?#65306;你无需为你不用的功能付出代价。使一个成员函数默认为非虚函数会违反这条规则,还会为?#25552;供高效的具体类型(concrete types)?#22686;加难度。对于那些认为?#31867;?#21363;为存在于复杂层次结构中的大家伙的人们来说,默认为virtual是显然的。一般来讲,虚函数不适合那些关键的小而具体类型,例如复数(complex numbers)、points、vectors、lists,以及函数对象。对于这样的类型来说,如下方面至关重要:表达的紧凑性、基本操作的内联化、访问的直接性、堆栈的配置,还有对?#37325;载函数不会对语义造成不希望的修改?#30340;保证。

此外,如果默认为virtual的话,你将需要一个non-virtual或final关键字,而且当过度使用它时会导致扩展性问题。在语言设计里,的确没有免费午餐。

Elden Nelson:在您看来,经由IEEE执行的标准化过程对C++语言的完备性、灵活性以及能力等方面产生了怎样的影响?

Bjarne Stroustrup:对于C++来说,ISO标准化过去以和现在都是重要的。其重中之重在于,标准委员会为技术人员提供了一个探讨技术问题的?#20013;立的舞台?#12290;还有什么别的地方能够让来自于相互竞争的机构(比如Microsoft、IBM、Borland/Inprise以及Sun等)的用户和编译器编写者们出于对用户利益着想,坐到一起合作共事呢?ISO的工作是民主的,是以大多数人的意见为基础的。为了达成一致的意见是需要时间的,但这样的努力非常值得。否则将导致语言的定义只为某一家公司(或少数几家公司)的利益服务。

由ISO工作而形成的标准C++比以前任何版本的C++都更加接近我的理想。标准C++的?#24322;常?#19982;我自己定义的几乎相同,模板更具灵活性,名字空间和运行时类型信息也被添加进来。从对编程风格(你也可称之为?#33539;型?#65289;提供支持的角度来看,其余内容皆属于细节问题,自然而然,标准委员会工作的主要部分便是精确定义这些细节。

鉴于接近标准的编译器可以广泛获得,人们试验那些新功能的时机已经来临。在几年之前很多东西还没有成为现实,如今可以在实际应用中使用它们了。那些对于大多数人来说仅能在语言定义上看到的技术,现在已被开发出来。例如STL(标准库中容器和算法的框架)就是一个有意思的新技术的优秀资源。

当然了,在接下来的关键项目中,你不应该冲到最前面使用所有语言特性和所有新技术,但是,是开始学习新语言特性和新标准库并试验它们哪些适合你哪些不适合你的时候了。

假如需要文档资料,你可以通过ANSI以18美元购得C++标准(参见 www.research.att.com/~bs/C++.html),也可以免费获得接近标准的草案。但是,这份标准并不是教本。我向有一定经验的程序员推荐我的《The C++ Programming Language》第三版,这本书以更易理解的方式讲述了完整的语言和标准库,它还阐明了C++支持的很多基本设计和编程技术。然而,即便这本书也不适合初学者阅读,因此,请先浏览我的个人主页(www.research.att.com/~bs/)以了解我的写作风格和详细程度能否满足你的需要。

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

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

如果你需要垃圾回收机制的话,你可以在C++应用程序中插入一个垃圾回收器。有不少免费的和商业的垃圾回收器已经在重要的实践中被证明非常出色(可以参见www.research.att.com/~bs/C++.html)。

如果你不想使用垃圾回收机制也没关系,你可以使用标准容器类,它们大大减少了对于显式分配和回收内存的需要。这样,通过使用现代的库所支持的现代的编程风格,你就能避免绝大多数内存管理问题。

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

C++提供了一些机制来管理常见资源。关键的手段 ?资源获取即初始化(resource acquisition is initialization)依赖于函数对象来管理生存期问题。语言中关于对象的部分构造(partial construction of objects)规则和异常机制对这项技术提供了一般性的支持。关于异常处理技术的讨论,请参阅The C++ Programming Language (Special Edition) 的新附录揝tandard-Library Exception Safety?#65292;它也可以从我的Web站点访问到(www.research.att.com/~bs/3rd_safe0.html)。

某些语言的狂热支持者总是用讽刺的手法来描述C++,然而C++实际上要好得多。特别是我认为很多其他特性已经被吹嘘过度了,而在C++中,通常这些特性能够很容易地被模拟出来。相反,新语言总有一种?#22312;损害一般性的情况下?#28155;加新特性的倾向,这也是一门新语言从诞生到被接受为一种用于常见计算的有用的工具,其体积和复杂度通常会增加两到三倍的原因之一。

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

精确区分语言和系统/平台之间的责任是一个困难的问题,我的观点是,它们之间应该有一个明显的分界线,并且,依赖关系应该尽可能地置身于语言之外,系统相关(system-specific)和系统依赖(system-dependent)的库才是解决系统依赖性的地方,而语言并不是。

我不认为组件版本管理之类的问题应该由编程语言来解决,这是一个系统范畴的问题,在语言里应该通过提供用于系统访问的适当的库来解决。C++有这样的机制。解决这样的问题并不会违背我对C++所奉行的理念。但在另一方面,给C++增加很多特殊的特性会使C++偏离轨道,而且在保持可移植性和平台独立性方面也是一个倒退。

Elden Nelson:如果为库中某个基类定义一个派生类,要想覆写(override)基类的一个虚函数,你就必须得到这个基类的源代码,以便获知是否需要调用基类中该函数的实现代码,您是否认为C++类库在这方面有那么一些失败?

Bjarne Stroustrup:唉,造成某些C++类库的这种缺陷的原因是,其设计者认为必须将此问题定义到他们的库中,并且一些用户认为他们必须以这种方式来使用库。这真是差劲的设计,是对C++差劲的使用!

如果你不想依赖基类的数据或者代码,就不要把它们放到基类中,这正是抽象类的使命。考虑如下代码:

class Reader {

public:

virtual bool empty() = 0;

virtual Element get() = 0;

};

它为所有派生类提供了揜eader?#21151;能的一个接口。Reader的用户完全不依赖于那些派生类的实现细节。尤其是当某个派生类的代码改动时客户代码并不需要重新编译。还有,用户可以同时使用Reader类的多种不同实现(也就是说,可以同时使用多个不同的派生自Reader的类)。

从1989年发布的2.0版起,抽象类就已被直接支持,并且这项技术/风格总是随时可用的。这些历史以及语言设计考虑在《D&E》中皆有描述,自然而然,The C++ Programming Language解释了在什么情况下以及该怎么使用抽象类。

随便说一句,通过继承一个抽象接口类,再继承某个类层次结构中一个具体类(以获得它提供的有用功能的实现代码),是多重继承的一个最简单、最明显的用法

class My_class : public Interface, protected Implementation {

// override virtual functions from Interface,

// implementing the overriding functions

// using facilities offered by Implementation



// Where needed, also override virtual functions

// from Implementation

}

我认为抽象类是一项远远没被充分利用的C++特性。程序员总是设计层次深深的继承体系,还在基类中添加大量数据和代码。有时这么做是有道理的,但在大的系统接口设计中,你更需要的是程序不同部分间的独立性,由抽象类提供的纯粹的接口往往便是更好的设计选择。较老的C++库的另一个问题在于,其设计者还不能使用模板。有些情况下继承的使用毫无必要或缘于无知,因为将类型参数化更加合适。

Elden Nelson:为什么在C++中没有关键词搒uper?#65311;

Bjarne Stroustrup:因为在C++中,它既非?#24517;要?#20063;不?#20805;分?#12290;

搒uper?#20043;所以不必要,是因为Base::f这种符号允许程序员表达f是揃ase的一个member?#25110;是揃ase的一个base?#12290;

搒uper?#20043;所以不?#20805;分?#65292;是因为你需要表达f来源于Base1而非Base2。

Elden Nelson:一些厂商已经或正在对他们的C++编译器进行修改,以支持平台相关的语言扩展。您对此有什么看法,您认为这会有什么作用?

Bjarne Stroustrup:我认为平台相关的语言扩展应该最小化,当必须进行扩展时,其设计应该局部化于库中。当然,比起我自己,平台供应商们倾向于认为要进行更多必不可少的扩展。他们还倾向于使扩展弥漫于应用代码之中,从而使用户很难更换供应商。身为一个注重可移植性的用户,我对这种套牢用户的伎俩表示遗憾。

出于用户的利益着想,理想状态必须是可移植的,且平台相关的代码应被隔离在应用代码的一些特别段落。可移植性,以及不因厂商的奇思异想而改变的语义,是一门标准语言比专有语言优越之处。我认为C++供应商们应该意识到这可以成为一个竞争优势,并将专有扩展及扩展所引起的冲击最小化。假如你想用Java和Visual Basic那样的专有语言,你知道到哪儿去找它们。

Elden Nelson:您对目前花色繁多的C++编译器有什么看法?请不要因为这是《Visual C++ Developers Journal》的采访而影响您的看法。

Bjarne Stroustrup:它们正变得越来越好。这包括所有C++编译器。我通常使用六种不同的C++编译器。几年前我是做不到这一点的,当时一些被广泛使用的C++编译器还不能完全满足我的需要。

我乐意让?#36825;是《Visual C++ Developers Journal》的采访?#30340;事实影响我要说的话。因为这正是鼓励微软更加遵循标准的绝佳场合!VC++已得到改进,但是凭微软所拥有的资源,还可以进一步提高符合标准的程度,并为核心语言特性和标准库提供更高质量的支持。例如,对于目前大多数C++编译器来说,关于模板的出错提示信息仍有较大改进余地。

遵循标准方面,现在的情况比以前要好多了,但在VC++中,我们仍然不能使用模板友元(template friends)和模板部分特化(partial specialization)功能。我非常乐意看到有人实现了对模板的分别编译(separate compilation) ?从Cfront时代起,它就是一项我想用而无法用的重要功能。

如果VC++能为新手学用标准功能打开方面之门,那将是一件好事。下边是那个没什么实际价值的?#31532;一个?#31243;序:

#include<iostream>

int main()

{

std::cout << "Hello, new world\n";

}

在我看来,略微提高投在标准库方面的资源,而不是提高投在专有扩展和专有功能方面的资源,将是微软帮助最大数量的程序员最廉价的方法。

通常产生的代码的性能挺好。基于用户社群不同的关注方面,各种编译器倾向于各有区别。我认为最重大的收益来源于对标准库的调整。例如,从一个istream中将一个字符序列读入一个string,就是一个值得优化的操作,不为别的,它可以避免程序员去摆弄诸如字符读取、显式缓冲、空间分配和指针之类的玩艺。举个例子,下面的代码既优雅又不失效率:

vector<string> vs;

string terminator = "endend";

string s;

while (my_input>>s && s!=terminator) vs.push_back(s);

请参阅我写的《把标准C++当作一门新语言来学习》一文中关于风格和效率的议题(我的損ublications?#39029;面有链接)。

Elden Nelson:标准C++并没有任何方式定义支持并发(concurrency)、持久化(persistence)和基于组件的编程(component-based programming),这导致了互不兼容的、平台相关的框架(例如CORBA、DCOM和SOM等)的繁殖,所有这些都有违直觉、杂乱无章,这不正表明标准C++应该为并发(尤其是线程)和组件对象模型提供直接支持吗?

Bjarne Stroustrup:?#24182;发?#21644;?#32452;件对象模型?#26080;疑是摆在当今所有语言的设计者面前的巨大挑战。不幸的是,这些挑战往往出于政治原因而非技术因素,有太多的金钱使之走样。

用户的理想语言应该是一门直接支持广泛的并发需求并对组件这一通用概念提供良好支持的语言。在理想状态下,程序员

posted on 2006-12-03 19:28 大龙 阅读(241) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理