数模论坛

 找回密码
 注-册-帐-号
搜索
热搜: 活动 交友 discuz
查看: 2563|回复: 7

[转帖]C++之父如是说----走近C++

[复制链接]
发表于 2003-11-19 20:17:28 | 显示全部楼层 |阅读模式

TechNetCast对Bjarne Stroustrup的采访

贝尔实验室

TNC:我们开场应该指明,我们目前所在之处并非C++孕育之地。

Bjarne Stroustrup:没错,这儿是AT&T研究所在Florham Park的新址。我在Murray Hill的AT&T贝尔实验室研究所旧址工作了16年。机构重组以后,从AT&T分离出来的那个建筑物归朗讯所有。我在AT&T研究所工作,它是AT&T保留的老贝尔实验室信息科学子部门。

TNC:您加入贝尔实验室以后感受到了什么样的文化氛围?对您的职业有何帮助?

Bjarne Stroustrup:在AT&T实验室,我感受到的 — 并在很大程度上保持至今的文化,是对年轻研究人员的大力支持和鼓励。与其他大多数地方相比,这里拥有更多的自由。这儿的文化氛围还在很大程度上鼓励“现实主义”,并在很大程度上激发了这样的知识:代码到底是怎么编写和使用的 — 不管是在高级应用还是在普通应用之中。

例如,关于如何将想法实现,我的友邻Al Aho给过我一些指教,他是世界级编译器专家,恰巧就在我隔壁。

同样,仅在跟Brian Kernighan、Dennis Ritchie和Stephen Johnson这些人的闲聊中我就获得许多帮助和支持。这儿资源极其丰富,我们不过利用了其中部分而已。

TNC:贝尔实验室的文化以及Dennis Ritchie、Brian Kernighan和Al Aho等“近水楼台”是否对C++语言的某些特性产生了影响呢?

Bjarne Stroustrup:很难具体说出是哪些东西受到了影响,毕竟当时我就处于那样一个环境中。正是Brian Kernighan,那时他设法(并且最终成功地)将一个常规程序中的普通指针全部替换为智能指针。他最终说服我允许分别重载“前置++”和“后置++”操作符。Stu Feldman对引入运算符重载机制影响很大。Sandy Fraser则帮助我将类看作为接口,允许将函数定义与类定义分离开来,而不象我在Simula中所做的那样,将其包含于类定义里。

Dennis Ritchie和Doug McIlroy给予我极大勇气,使我在“参数列表为空的函数的声明”这个问题上与ANSI C绝交。为了保持与K&R C兼容,我为C with Classes发明了

int f(void);

记法。最初,我保持了

int f();

这种写法的原来含义,即f()可以接受任意参数,这正好与f()(不可见的)的定义兼容。Dennis和Doug称f(void)风格的声明让人生厌,因此在C++中

int f();

现在有了明显的含义,即“f()不带任何参数”。不幸的是,ANSI C采纳了f(void),因此为了与ANSI C兼容,我不得不将它也引入C++。

你在《D&E》中可以找到更多类似的例子。




 楼主| 发表于 2003-11-19 20:20:03 | 显示全部楼层
编程与写作

TNC:能否介绍一下您的写作习惯?

Bjarne Stroustrup:我想关键在于我尽量通过例子来写作。因此,关于“什么可以进入一本书或一篇论文”的诸多考虑就在于它是不是一个好例子。

假如你留意过我的写作风格,你会发现有这么一个特点:两三段文字,然后一小段代码,然后又是一两段文字,再接以一些代码。而不是一大段代码示例,然后一大段文字说明。我在挑选例子方面花费了大量的时间。

TNC:您将多少时间用于写作?有波动吗?

Bjarne Stroustrup:实际上有很多变数。目前我在写作上没投入多少时间。在完成《The C++ Programming Language》第三版,并写了几篇关于标准的论文之后,我有点倦于写作了。现在我正在摆弄一个编译器。

倒回几年去,我还在忙于构建系统。再倒回几年,你会看到我又在写作。事情就是如此,宛若潮涨潮落。

TNC:您喜欢写作吗?

Bjarne Stroustrup:这我可说不准。“该写一本书了”的主意来源于我工作上的邻居Al Aho。当时我正站在他门旁抱怨用户提了太多太多的问题,而且总是就相同的问题问个不停。他便说:“唔,你要知道,Bjarne,很明显你需要写一本书了。”以前我从来没干过这种事,于是我便坐下来写了这本书。

我不能确定自己有多么喜欢写作。这是个苦差事,而且随着写作量的增加,难度也会增加,因为人们对你作品的期望值以及读者数量都在增加。因此这就成了一件颇为严肃的事儿。

我真正体验到写作的乐趣在于《The Design and Evolution of C++》的写作过程中。其中,我可以记述那些曾经发生的故事,做一些在教科书或学术论文中不能做的事。可以对朋友们致谢,还可以说“我之所以这么做是出于这些原因”。并非一切都是严格的学术性的东西。我还可以说“我把这个特别之处搞糟了而那儿并没有”,还可以说明有什么东西没有发生,并解释原委。

这类内容在一本正规的教科书中是没有容身之地的。因此,我乐于写的是《The Design Evolution of C++》这本书。

TNC:您可以对“思考过程”与“写作和软件开发以及对软件设计的思考”的创造性过程加以对比吗?我有时候认为编程是受限制的,往往在经过一段较长时间编程后,我就会有这种想法。编写软件需要仔细考虑某些方式,比如一门计算机语言提供的一些方法和抽象机制。而写作则是一项更具有创造性的劳动 — 自然语言显然更加丰富更加微妙。您是否同意这一观点?

Bjarne Stroustrup:我认为编程语言要比你说的更加微妙一些。有时我会说,写代码与其说像是在写散文,不如说是在写诗歌。它更注重结构。

与写文章相比,我更喜欢写代码。

写代码可以马上得到满足感,这种回馈你无法从写文章中获得。而且写代码的标准则更加客观。你可以看看代码的尺寸、运行速度以及代码结构的整洁性。真的很明显,这种感觉很棒。

而且你无需为“教学”问题烦神,你只有一个观众,它有着良好的定义。

当我写一本书时,我知道它将被成千上万人阅读,但我不认识那些人,也不了解他们的背景,这使得要做到清晰、简明、准确并易于理解非常非常困难,而写代码时我就没有这些麻烦。


 楼主| 发表于 2003-11-19 20:21:32 | 显示全部楼层
Internet和分布式计算

TNC:您用Internet有多长时间了?  

Bjarne Stroustrup:我想我与它初次会面大约是78年在剑桥的时候。当时是ARPANET在支撑着它。它触及的范围越过了大西洋。当然了,自从79年到了AT&T贝尔实验室以后,我就或多或少一直在使用它。在早些时候,当然主要用它来收发e-mail和传输文件。

实际上,近20年来,我都是生活于Internet之上。10多年来,我收发的绝大多数邮件都是e-mail,而非纸质邮件。早期大多数软件的分发也是经由Internet。

TNC:您最初是何时认识到Internet对大众会有像今天这样如此大的吸引力的?

Bjarne Stroustrup:我想,事实上,当这成为现实之前我并没有认识到这一点。我当时忙于语言层面的技术工作,只把Internet用作一个工具。我非常高兴看到它速度越来越快,用起来也越来越简单,但是我也只是个用户而已。

尽管我有分布式系统工作背景,但我对其最终用户方面的东西兴趣不大。

TNC:从什么时候起您明显认识到网络不仅在改变着软件的发布传播方式,而且也在改变着软件的设计方式?

Bjarne Stroustrup:这我不很确定,不过我可以肯定在80年代初期它对软件的分发起到了极好的作用。不仅是软件,还包括与软件相关的新闻消息。假如没有文档或教学,大多数软件系统发挥不了什么作用。(关于Usenet、新闻组和分布式系统之类的最初的两三个系统,我参与过其中之一)

我不能肯定软件设计方式在多大程度上已被改变了,对此已有大量讨论,而且无疑今天很多与Web相关的软件的设计方式被改变了。但在很多软件中,应用程序是与用户接口脱离的。我认为这种思想非常好,事情本来就应该这样。你可以集中精力分而治之。其他情况下,软件只是运行于某些小玩意上,而不是运行在特定的分布式世界里。“分布式机制”伴以数据和代码的传输,这并不是什么新玩意儿。

TNC:您提到了您有分布式系统的研究背景,在您的博士研究工作中您专注于此。在《D&E》中,您指出那段时间让您明白了“将良好划分的模块组装成软件”的能力的重要性。

您开始进行关于C with Classes(最初的C++)的工作是为了帮助编写一个分布式Unix内核。为了完成任务,您需要以更加模块化的零件,对问题域进行分解并组织程序。我记得在某处您使用了明确的模块化(express modularity)这一术语。

与此同时,您甚至提出为了表达并发机制(concurrency)而为语言增加原语支持(primitives)的思想,这发生于C++最初的日子里。

因此,在C++发展初期,似乎有这样一种意图:不仅为了编写通用系统,还特别针对分布式系统创造一门语言或者工具。  

Bjarne Stroustrup:是的,而且从简单意义上来看这一意图已经取得了成功 — 已经使用C++编写了大量的分布式系统。

一件仍未变得轻而易举的事情是编写真正简单的分布式系统。原因之一在于我坚信实现并发有很多方式,而我不想将语言局限于其中任何之一。因此,你不可以简单地说“这便是在C++中实现并发的方式。”

搞数据库的伙计们有一种“并发”概念,另外一些人则使用进程和线程包(processes and thread packages)以便在C++中使用系统的原生功能,但语言自身并不携带一个特别的并发模型。

TNC:那方面属于库的领域。

Bjarne Stroustrup:没错,那的确是库该关心的问题。C++中没有专门的并发特性显示出我对此问题的关注以及我对这个领域重要性的评估。

“在语言中构建一个单独的解决方案”有很大的局限性。我这儿书架上有一本关于C++并行编程(parallel programming)的书。它讨论了很多解决方案,并展示了人们在此领域业已取得的成果。

TNC:许多类似的问题语言都没有直接解决。而且语言并不包办一切,实现细节和专门的解决方案都留给外部库来处理。C++的本质特征正在于此,当我们拿它与其他语言进行比较的时候,这一点就更加明显。

Bjarne Stroustrup:这是经过深思熟虑的结果。在C++创建之初,我曾经表达过这样的观点,我当时说,计算问题已经被Dennis Ritchie解决了,而我要处理的是程序的组织问题。一些新型的高性能数值计算库就是这一例证。他们似乎是在Fortran的“主场”与它较量。我猜测在Fortran的“主场”你很难真正击败它,因为机器在骨子里就是专门为Fortran设计的。但是, 通过更好地利用资源,更少地使用临时变量,以及善加利用其他手段,你可以和它打平,有时甚至可以获胜。这是对这门语言的一项非常有趣的应用,也是它被如此这般地设计的结果 — 它被设计为一套基础设施,用以创建新的抽象和库。

TNC:您曾经说过,您希望看到有更多的库来扩充语言功能,尤其是应用相关的库(application-specific libraries)。您还希望这些库能提供一种“新风格C++”接口。现在情况如何?您认为您所说的话引起呼应了吗?

Bjarne Stroustrup:我认为现在仍然才刚起步。我希望我的话能起到作用,而且我们已经看到了一些基于标准C++所提供的设施而设计的新库。对此,Blitz++和MTL都是例证(请参考我的个人主页)。在关键的数值应用领域,它们可以与Fortran匹敌甚至胜出。我希望看到各个领域出现更多优雅且不失效率的库。

TNC:就像STL用于通用目的的、容器相关的算法那样,有没有可能出现一个分布式算法泛型库以用于分布式算法?这个库可以为分布式计算提供一个运行时(runtime)或环境。

Bjarne Stroustrup:我认为这是可能的。换句话说,我认为编写一个“为可运行于多个处理器的容器和算法提供整洁接口”的库是可能的。我怀疑这个库的用户接口看起来与STL非常类似,现在就有向这个方向进展的试验。

另一方面,我不认为单单一个库就足以支持C++社群所需要的所有形式的并发要求。我认为我们还需要一些支持常见技术风格的库。比如说,我猜想我们应该有一个标准线程库、一个标准的重型进程(heavy-process)库,还有一个用于低阶并发控制的相当标准的原语集。全部拥有这些库或只有其中之一就会给C++社群带来福祉。主要的问题在于,不同的平台供应商更乐于提供并支持他们自己(专有)的解决方案。

标准委员会考虑过这个问题,并且得出结论(我确信这是正确的):在尽力及时地提供新标准的同时,委员会没有资源来解决关于并发的问题。可能会有人会为每五年修改一次的标准提出一个重大的提议。然而,要想成功,被提议的库或者库的家族应该足够精彩、足够伟大(就像STL那样),否则,就不会激励那些已建立的C++库的用户和厂商们予以协作。

值得记住的是有很多优秀的C++并发库。

TNC:分布式系统很容易变得极其复杂化,如果有一些语言解决方案来表达分布式计算和并发的某些概念,是否会改善这一状况呢?

Bjarne Stroustrup:假如你有了某些语言设施来支持你所需类型的并发操作,当然会有所改善。问题在于并发有多种要求:存在于一个地址空间中的各个线程,存在于一台计算机里的不同进程,还有跨越某个局域网的分布式计算,以及在某个广域网上的分布式计算,它们的要求各不相同。这项工作有着不同类型的约束,它们依赖于你是在做一个高可靠性的事务(例如金融或者性命攸关的事),还是某些允许失败的关于Web的东西。

我认为没有人能够提出一个可以很好地满足所有主要应用领域的并发原语集(a set of concurrency primitives)。

TNC:现在世界各地的机器都通过Internet互连,包括主机、工作站、商业系统甚至还有家庭PC。但是,似乎软件 — 特别是编写软件的方式,并没有跟上发展步伐。

可是,从以上观点来看,未来的程序设计显然是关于分布式计算的。

Bjarne Stroustrup:我同意软件似乎确实没有跟上步伐,但我认为许多分布式软件是由分布式零件构成的,很多逻辑可以而且应该是分开的。

在很多情况下,用户接口与应用程序之间的集成都过于紧密了。在我看来,这导致软件设计难度加大,难于修改和调试,同时也使得“从一个环境取出一些东西用到另一个环境”更加困难了。

在这些领域中,“所有计算机相互连接”赤裸裸地暴露了它自身的问题:系统的一致性、安全性和保密性。在这些领域中,我们解决问题的力度只能算是蜻蜓点水。

TNC:与在非并发系统中相比,基本并发编程涉及到的一些算法的复杂度要高一级。尽管我们可以想象一个程序员可以重新发现一个简单的排序例程,但一个程序员自己却不大可能重新发现用于并发编程的哪怕简单那么一些些的算法。同时,这些算法和解决方案若可以轻松获得且为人熟知,那将对构建高效且设计良好的分布式系统意义非凡。

鉴于“基于语言”的解决方案看来并不合适,那么为了达到这一目标,将逻辑进行打包的最佳方式是什么?

Bjarne Stroustrup:首先,我不认为普通程序员能够白手起家发明一种优秀的排序算法。优秀绝伦的库可以解决这个问题。

从前,“发明”排序算法属于程序员的工作范围。时至今日,几乎所有程序员都“使用”排序算法,还有少数一些专家倾注精力提高特定用途的技术发展水平。

我们需要以类似的隐式方法来处理并发问题,普通程序员无需处理复杂的并发操作。如果并发被内部化于类或对象,那么处理起来就容易得多。我认为可以将许多并发机制进行打包,如此一来,最终用户只需隐约知道到底发生了什么事儿就可以了。


 楼主| 发表于 2003-11-19 20:22:06 | 显示全部楼层
基于组件的编程与类的演化

TNC:我们正在讨论关于分布式系统和基于组件的软件,当然了,目前这都是热门话题。您发现了哪些解决方案,适合于解决“基于组件的软件开发”所试图解决的问题?

Bjarne Stroustrup:我正在进行一些项目,试图了解更多的和该主题有关的内容。AT&T内部很多项目使用了各种形式的组件架构。COM和CORBA都是可以立即映入脑海的例子。

这些概念似乎很健全合理,而且我们正在获得技术和实现品。以C++的观点来看,我认为问题之一在于,这些粘合物(bindings)仍显得有些低级原始,而且往往倾向于以C来实现。例如,标准的CORBA粘合物并不支持C++标准库。而COM解决问题的标准方式要求“每做一件事需要在三个地方填表”。因此,我认为它们还有很大改进余地。

不过当然可以肯定的是,在构建分布式系统时,这些技术是派得上用场的。

TNC:今天的操作系统提供了拥有共享的动态库的能力。这已自然而然成为分布式组件的首选方式。

这些解决方案生来就是动态的,而另一方面,C++粘合物内在就是静态的。一个C++ class要想动态地进化而又不想重新编译,需要使用一些并非总是直截了当的惯用手法(idioms)和技术。

Bjarne Stroustrup:如果你有一个提供二进制接口的平台,你可以把这些东西勾连在一起。多数平台还没有标准化到这种程度,但是沿着这个方向的工作一直都在进行。

在Windows平台上,倘若两个不同的C编译器的C调用序列不同,它们编译产生的库就不能连接(link)在一起。对于C++来说同样如此。要是你遵守同样的对象布局和调用序列的话,这种连接行为则是可行的。我了解到有几个平台正在努力建立这种二进制标准。

但是,只要我们拥有不同的平台,只要人们还在试验这些平台的新用法,我们就不可能获得一个完美的二进制标准。我认为说不定这是件好事,因为一旦你有了一个“完美”的二进制标准,除非它真的完美,不然你麻烦更大。

TNC:C++对象模型与组件对象模型之间的“汇聚点(convergence)”是怎样的?现在程序员先用C++设计classes,然后再在一个组件框架中描述与之相关的对象。很多情况下,组件对象只是C++对象的一个包装器而已。

是否存在一个可以利用的“汇聚点”?

Bjarne Stroustrup:我希望会有这样一个“汇聚点”。但是人们应该意识到,没有任何一种对象可以服务于所有需求。一个“printer spooler”可以被看作一个对象,而且可以作为一个COM或CORBA对象来操控。一个浮点数或一个复数也可以作为一个对象同样可被操控。但是,这些操作的实现品却有关键性区别。你需要的服务种类以及与这两类对象的通信方式是不一样的。

一个“point”不同于一个“printer spooler”,反之亦然。因此,我希望看到C++语言设施与对象模型间有更自然的映射。没有什么特别理由使你不能说class point只是一个稀松平常的class(a plain old class),而且你可得到所有常用的绑定功能。这个恰好被称为“printer spool”的class应该具有该类对象所有功能,并且与之通信就应该遵守标准规定的所有规则。这里的“标准”指的是业界标准。

现在你就可以这样做,只是目前这太困难了。

TNC:为了支持专门的组件对象架构,编译器厂商们对其编译器做了专门修改,这合适吗?

Bjarne Stroustrup:这要看是什么类型的修改。我将其分为“良性”修改和“为了套牢用户”的修改。

我属于那种“对含有关键字near和far的C不太反感”的人。我将它们视为良性的。它使我得以从硬件架构的某些特性中获益。假如我不需要near和far的话,我可以将它们define为空,我的程序该是什么还是什么,它的语义并没有发生变化。

同样地,我可以设想,一个组件和一个非组件对象之间唯一区别在于前者拥有一个基类或是有一个“前缀(prefix)”,它们可以为对象附上一些详尽的协议,以提供可靠性、分布性等功能。但两者的调用语义和代码语义仍然是一个样子。

因此,我乐于看到那些诣在“允许用户控制使用什么样的通讯协议”的最小限度的修改,而非任何深度侵入语言的东西。

我尤其讨厌那些改变了语言含义的附加物。假如有一行代码x+y,你会希望它的意思与标准中定义的一致,而不是仅仅因为某人在一个头文件中声明这应该基于X公司的规则来解释,而使它面目全非。

TNC:这个问题的部分动因在于,MS试图将以IDL表达的组件属性融入C++类的声明中。如果我没记错的话,在VC下一个发行版中,包含于.h和IDL文件中的声明将以某种方式合并于一体。编译器也编译IDL,并生成COM胶合类和C++代码。它还支持一个interface关键字,类似于Java的interface或Objective-C的protocol类。

Bjarne Stroustrup:这儿有好几个问题要谈。显然,你也希望从C++语言设施到组件或分布式模型的映射尽可能地简单、直接和方便。我认为这是可能做到的。当然了,在COM中你要想将一个class映射为一个组件对象就必须“登记好几个表”,目前的状况非常繁琐,并不理想。我们真的应该在一个支持组件模型的环境下编写C++程序,而无须担心繁复的语言机制、代码生成器和宏之类的东西。

额外的关键字对此是否必要或有所帮助尚不确定。不过可以肯定的是,这有可能把事情搞糟。然而,我找不到任何理由,说明没有人能够在无需侵犯类型系统或标准C++的其他规则的前提下,提供一个对于语言相对无害的编译指示符,以表达“映射这个class”的意思。这有可能采用关键字的形式来实现。若你需要将代码移植到一个不同的系统,你可以在移植过程中使用“#define”去掉它,我猜想“额外的关键字”方案会使移植者的工作量最小。我还认为“对象映射”可被局部化且不会对普通代码的语义造成广泛的连带影响(尽管可能造成编译器拒绝某些与对象模型不符的构件(constructs),例如指针传递等),非常重要。

这种方式可能让人讨厌的是,需要遍及程序使用大量的关键字,而且还可能导致改变ISO所规定的语义。

TNC:C++这门静态语言中的粘合物(例如变量、函数和类)被有意设计为本地决议(resolved locally),且发生于编译期或连接期,而动态、分布式系统则将检查和绑定推迟到运行期。在这两者之间是否有着一种基础性的、概念性的对立呢?

Bjarne Stroustrup:我不这样认为。一个对象拥有一个特定的接口,且连接器已校验了你所使用的接口是否正确,倘若你了解这一点,基于此思想,你可以构建非常成功的系统。这个观念不会受“分布式”严重影响。请考虑对CORBA接口的静态调用的例子。就其基础类型系统而言,它几乎都是纯粹的C++。只要在可行的情况下,我都倾向于这样的系统观:类型的检查和匹配发生于连接期或装载时,使用它们时就不必进行解释和运行时类型检查。当然了,很少有哪个大型系统可以做到完全静态检查,但再一次,这不属于分布式系统的功能。

可以正确处理“模板分别编译”的连接器对此有莫大帮助。

TNC:您在《D&E》中用到了的“类的演化(Class evolution)”这个术语,它包含有这样的能力:更新类的私有实现和协议而不会破坏客户代码和重新编译。但在C++中,这并未被证实简易可行,它需要刻意的设计努力(参见John Lakos的书,或MS COM编程惯用法)。与此同时,这一问题对于基于组件的软件的分发又是至关重要的。在C++中如何解决此类问题?值得对此提供语言支持吗?果真如此,这种支持会是什么样子?

Bjarne Stroustrup:我认为对于任何系统或语言来说,类的演化都不是轻而易举的。在标准C++中,我最喜欢的技术是在一个名字空间中定义接口,这样我便强制只有改变这个名字空间才需要重新编译和重新绑定(参见《D&E》)。然而,我不知道这种技术在多大程度上可应用于更新频繁的大型分布式系统。假如存在一种简单的解决方案我不吃惊才怪。

我所钟爱的“避免因为修改基类而破坏客户代码”的方式是,只要将主要的接口定义为抽象类即可。这样的话,所有实现细节都在派生类中完成,基类中不存放改变后就会引起重新编译的私有数据,公开接口从而可以保持相对稳定。

TNC:连接(linkage)是动态类装载(dynamic class loading)问题的后半部分。一个动态的运行期连接器是否可以成为一个合适的解决方案呢?或者这有可能用名字空间(分布式名字空间)来表达?

Bjarne Stroustrup:两者皆有可能。肯定需要一个运行时连接器,而且,在实际的分布式系统中,也许名字空间或其他类似的东西是合适的连接单元。不过,在这种场合下,名字空间似乎并非具有本质意义或不可或缺,对它们的使用不过是一种良好的编程风格而已。

TNC:所有这些问题的一个共同的解决方案 — 与“通过库来扩展语言”相关联的方案,可以一个C++标准套接字(sockets)库来实现构建分布式运行时功能。这样就可以在不破坏C++核心架构和C++“精神”的前提下,将Java或组件对象模型的一些分布式特性,基于这个标准库,以一种标准的方式添加进来。

Bjarne Stroustrup:这是个好主意。然而,这也正切中了C++与有着良好财政支持和团体赞助(或国家赞助)的语言相比而言的主要弱点。谁会为这样一个库的开发、发布、市场营销以及维护提供资金?哪儿有这样的意愿,就会在哪儿找到此问题的答案。例如,一些公司开发了可用的高质量的库(请考虑HP和SGI对STL的支持以及对STL的进一步开发)。还有“开放源码”的支持者们(考虑比如Cygnus开发的EGCS编译器及其搭配的库)。但是,对于一个语言社群来说,没有一个大的“赞助商”或“扶植者”的日子可不那么好过。

TNC:自C++的工作开始至今,您是否认为发生了一些根本性的变化了呢?比如说,在以前,重点在于静态检查、与C兼容(尤其在连接方面)和性能。这些方面对于C++的成功很关键,但今天看来它们似乎不那么紧要了。如果现在再来设计这门语言的话,C++的设计目标和关注焦点是否会有某种程度的变化呢?

Bjarne Stroustrup:也许有些地方发生了根本性的变化,不过,对于很多应用领域来说,静态检查、与C兼容以及性能仍然至关重要。这也正是C++的使用仍然稳定增长的原因。我能想到的唯一一样始终超过硬件性能发展速度的东西就是“人们的期望”。

对于一门高效灵活的通用编程语言来说,在未来数十年仍将有强烈的需求。就目前而言,对于范围极广的有着严格要求的应用来说,我认为C++是最佳选择。

一种优秀工具的老化速度要比某些人想象的来得慢,新工具的成熟速度同样如此。

我宁可不去猜想假如一小段时间以前我才刚开始设计C++的话,它看起来会是什么样子。一门语言是针对一系列问题基于一系列原则的解决方案。假设没有C++,我难以估计出几年之前我所决定的待以解决的问题。我猜想我对静态类型检查、效率以及通用性的关注已经在某些方面证实了其效果,我在抽象技术和模块化方面的兴趣亦然。


 楼主| 发表于 2003-11-19 20:22:51 | 显示全部楼层
新风格C++

TNC:让我就“新风格C++(new style C++)”问题向您提问。

今年早些时候,我听了您的一次题为“作为新语言的C++”的演讲。您指出C++新近加入的内容使之更加安全、更加高级。您还号召程序员们努力学习并以这种新风格编写代码。您能否就此详细阐述一下?

Bjarne Stroustrup:对语言作出修改并加入标准库的目的之一当然是为了使一些东西更简单更好。只有改变了思考问题的方式,我们才能取得这种重大变革。否则,我们不过是以一种新语法来实现一些老旧内容罢了,那样我们只能略微得到一些改进。

我认为将C++作为一门高阶语言来使用是可能的。有一种非常简单的“起步走”的方法:尽可能使用strings来代替字符数组;尽可能使用标准库的算法,而不要自己随意编写代码;使用vectors、lists和maps,避免使用数组。这样就可以立即大幅提高代码的抽象水平。

我将标准库视作这种新型库的一个先锋榜样,它允许我们封装概念并使其易于使用。我希望大学和商业组织能够开发出许多有意思的库。

TNC:您是否认为C++的低阶C出身给提倡安全高阶编程的程序员造成了障碍呢?

Bjarne Stroustrup:或许吧,但对我来说不是那样。我选择C作为我工作的基础,是因为我需要可以相当直接地表达关于“机器(machine)”的东西。“机器”是具有地址和对象序列的东西。除非你能够对它们进行高效的操作,不然你就会沮丧不已。

你可以使用别的机器抽象机制,而且有些还相当成功。但我所就选择它了。因此在底层,在根本的层面上,你可以使用“机器” — 或说是C++中来源于C的内容。你可以利用它们构建更为有趣的东西。

我们不应该始终总是(直接)使用整型(integers)、位(bits)和字节(bytes)这些东西,而且也没那个必要。

TNC:您时不时地建议程序员自上而下学习C++,即从高阶构件开始,忽略语言的某些低阶特性。您认为这可能吗?

Bjarne Stroustrup:哦,是的,我认为这是可能的,因为我已看到它的确可行。你可以从使用vectors、strings和lists开始着手写程序,而把那些指针,尤其是有趣的用户指针放到后面学习,数组也稍微迟些再接触。

Andrew Koenig和Barbara Moo去年在斯坦福暑期学校开设了一门课程,内容与前年相比作了全面的修整,实际效果是可以2天时间完成原来需要5天时间的教学。这是以“添加一个支持新观点的库”的方式而达到的。


 楼主| 发表于 2003-11-19 20:23:45 | 显示全部楼层
嵌入式C++

TNC:为了使C++更加适合于嵌入式系统,您能否介绍正在进行哪些工作?有哪些问题?该如何解决?

Bjarne Stroustrup:C++一直被用于嵌入式系统。我想大约在1983年时,我用C with Classes写了第一个下载到一个“并非是典型计算机的一个组成部分”的处理器中的程序,我也并非第一个做这种事的人。

标准C++极其适合于嵌入式系统编程,因为它全面支持各种高效编程风格。特别是,C++保持了C直接而高效地操纵各种硬件实体的能力,比如字(words)、字节(bytes)、位(bits)、指针(pointers)等等,这往往至关重要。“零开销原则”(“你不必为你不使用的东西付出代价”,请参考《D&E》)可以确保优雅的设施能够通过这些接近机器的设施“经济地”构建出来。重要的是,利用自由存储配置之异常机制与异常处理机制,你完全可以预见每一项C++语言特性的性能。

我认为没有什么工作急需进行以使得标准C++适合于嵌入式系统编程。证据在于C++实际上正被用于要求严苛的嵌入式系统应用中。当然了,一个关注运行时效率、空间效率和可预见性的程序员,比一个可以忽略这些事项的程序员必须要对C++有更多的了解。然而,这并非C++的“专利”。

如果一个设计要求程序员禁用动态配置机制,那可以轻松避免之,甚至还无需放弃泛型和面向对象编程带来的益处。与此类似,我还见过避免使用异常及某些标准流(streams)的应用,那有何妨?通过禁用或废除少量功能,相对于C或汇编来说,C++仍然拥有大量优势。如果你能够承受C,并且在你的硬件平台上有一个可用的C++编译器,你就能够承受得起C++。对于很多嵌入式应用,甚至“异常”都是承受得起且有用武之地的。

可能你所谓的“嵌入式C++”指的是由日本嵌入式系统工具厂商们提议的一种C++方言吧?如果是这样的话,我可以补充一句,我认为这种截取子集的思想已经过时了。对于复杂性和效率低下的忧虑从未有过什么充分的理由,而对稳定性的担心,也已随着近几年ISO标准C++的标准化和去年对它的最终一致批准而烟消云散。

这也并非说C++就完美无缺了,或者没有什么工作可以(以多种方式)使C++编译器更加高效并且可预见了。ISO C++标准委员会成立了一个下属组织,专门研究诸如此类的问题,它们与嵌入式系统开发者以及对性能的关注超出常规的另外一些社群相关。


 楼主| 发表于 2003-11-19 20:25:32 | 显示全部楼层
编程语言与抽象

TNC:为什么我们要坚持编程语言简单易学呢?我们是否应该让专业语言(professional languages)多产、高效、表达能力强、通用、安全 — 哪怕这需要一条非同寻常的学习曲线?我们不指望自然语言简单,相反我们希望它们丰富而复杂。

Bjarne Stroustrup:那或许只是一厢情愿而已。很多人似乎认为一门“在一周内不能交付一个半成品玩具”的语言过于复杂,很多教授仅有一个学期时间用于向半数勉为其难的学生讲授如何编程,很多人不大情愿同意“严肃的编程并非适合于所有人”。

我注意到《The C++ Programming Language》(第三版)只比我女儿大三的生物化学教材稍薄一点。可没有人注意到这个奇怪的现象:如果不能心甘情愿且有能力在一年内消化那本书的话,你就不可能被承认为哪怕是最初级的生物化学家,也不可能去从事与之相伴的实验室工作。另一方面,很多人好像反对这种观点:一门提供类似数量信息和实践工作大学课程,对于一个人成为一名初级程序员是必需的。并非C++自身需要很多个月才能学会,而是它所支持的基础编程风格使然。

我认为,所有语言一开始出现的时候,“造反派”们手中都挥舞着一个武器 — 与遗留语言吓人的复杂性相比的“简单性”。一旦尘埃落定,新语言就获得了与其他成功语言相当的设施和复杂性。这已发生在所有成功语言身上(当然也包括一些不成功的语言J)。一门通用编程语言服务于形形色色的社群,为了提供支持,我们需要丰富多彩的设施。

TNC:我听Bertrand Meyer说过面向对象将会永存,因为它源自这样的合理性:以某种天生自然的方式来理解问题,并对问题进行分解。但是,它之所以合理难道不就是因为它行得通吗?能否想象在不久的将来会出现新的抽象机制取而代之?我们编程时常用的抽象基础是什么?

Bjarne Stroustrup:Bertrand Meyer这个观点是正确的,问我我也会给出类似的回答。我通常还会引用Kristen Nygaard的话,他是Simula的设计者之一,也是“OO之父”称号的主要候选人,对此问题他给出了简明扼要的陈述:“可能会出现一些别的东西,但OO将会存留,就象加法在乘法发明之后仍然保留下来一样。加法具有基础性的意义,不论其他什么东西被添加进来,加法仍会作为任何健全的算术系统的一个组成部分。类似地,OO将会成为任何完整编程系统的一部分。”

请注意,这根本不同于“所有编程都应该是面向对象的,所有优秀的程序都是OO的”狂热的错误说法。几年前我为OOPSLA就此话题做了一个题为“为什么C++不仅仅是一门面向对象的编程语言”的报告。这篇论文可以在我的个人主页上找到。

TNC:结束之前,让我问您一个在采访结尾不可错过的问题:标准化工作完成以后,目前C++有哪些发展方向?

Bjarne Stroustrup:我想首先是稳定性。我们必须让所有编译器跟得上标准,我们还必须使各种标准库实现品在语义和性能两方面保持一致。

库的设计方式使你可以获得非常好的效率。这种效率你无处不需,这样,用户就可以在更换库的同时还能获得同样的性能。

一如既往,我希望看到比目前还好的“支持代码分析和代码检查”的编程环境。我还希望看到很多很多以更直接的方式支持概念(concepts)的库出现。并发控制(Concurrency)是一个方面,但还有应用(application)方面的概念,以及我们谈及的组件模型。我还希望看到这些方面的高阶粘合物(bindings),并希望这些粘合物能够恰如其分。

TNC:您自己认为会出现一个“后C++时代”吗?在此您能给出一些预想吗?

Bjarne Stroustrup:或许吧,不过现在我还是想用C++和一些别的东西编写代码。

TNC:非常感谢您欢迎我们来做客。
发表于 2003-12-1 08:53:43 | 显示全部楼层
突然发现 懂得了很多
tks
您需要登录后才可以回帖 登录 | 注-册-帐-号

本版积分规则

小黑屋|手机版|Archiver|数学建模网 ( 湘ICP备11011602号 )

GMT+8, 2024-5-10 20:19 , Processed in 0.055192 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表