咨询培训 著译作品关于荣耀 Bjarne Stroustrup 网络资源 浣石山房在路上 联系站内搜索首页

Bjarne Stroustrup

Carlo Pescio博士对Bjarne Stroustrup的采访

马皓明 翻译 荣耀 指导

www.royaloo.com

CP:您对C++标准化工作的成果与进度满意吗?我的意思是,一方面,这是语言成功的一个证明,但另一方面,也增添了许多“官僚作风”。您失去对核心语言议题的原始特权了吗?

BS:当然了,我的耐性受到了巨大考验,但总的来说,我对C++标准化工作的成果是满意的。即使存在少许异议,ISO C++将会包含我认为确实需要的特性,且不会包括我认为有害的特性。与C++的早期版本相比,ISO C++是一门更强大、更一致的语言,它没有添加任何未经我研究并认可的特性。ISO C++的某些细节可以显示出“由委员会设计”的迹象,但整体功能集与更早的版本相比更符合我对C++的原始期许。

我参加标准化工作的主要原因是召集成立委员会之时我还未能将语言完成。缺少模板和异常机制的C++是不会受欢迎的,而缺少名字空间和运行时类型信息的C++也会让我们感觉比现在的C++低劣很多。

我的“原始特权”很容易被夸大。我早就决定让我的语言与C兼容并支持真正的用户。这就给我能够做些什么加上了限制。我想另一种选择就是设计另外一门宗教式语言。我无法等待标准的最终完成。C++社群需要的是一套稳定的标准,而我需要的是近6年不得不投入标准化工作中的时间。我在标准委员会的工作让语言受益良多。我是“扩展”分委员会的主席,这个团体处理所有关于扩展的请求以及语言的其他主要改变。我经常参与最重要的议题,包括标准库的设计。像C++这样拥有这么多用户的语言是必须标准化的,然而我不能把标准化称为一个娱乐活动。许多荣誉 — 比通常归属“姓名不祥的委员”数量更多的荣誉 — 应该归属于那些常年为标准义务性付出大量时间和努力的人们。在我最近的书《The Design and Evolution of C++》(常被称作D&E)中我记录了很多这些人的姓名与他们做出的贡献。

CP:许多读者想知道是否有一本《The C++ Programming Language》第3版或者还有一本ARM第二版正在进行中……

BS:我正在写《The C++ Programming Language》第3版并在考虑用什么东西来代替ARM。但是,除非有许多新内容要讲,不然我认为没必要写一本新书,因此进展比较慢。我的目标是让第3版对第2版的改进就像第2版对第1版那样。换句话说,我想创作出比第2版更容易被人接受的新内容,展示给每一位C++程序员。我无法预计何时完成,但想找一本好教材的人没必要等待第3版出版。第2版仍是一本最完备、透彻并且最新的可用教材。自然,在出现一套需要注解的标准之前,我无法出版一本ARM替代品。在我写完这些书之前,D&E是关于新特性以及专门解释C++设计背后一般原因的最好资源。

CP:回头望去,您想改变哪些关于C++的技术性决定?不是指那些您无法让C++接受的东西,而是已由进一步经验证明存在某种缺陷的东西,还包括假如当时有机会您会改变的东西(尽管现在出于兼容原因已不可能再改变了)。

BS:有许多我想小修小改的细节东西,但没有任何主要特性是我想删除的(即便我有那个能力),也没有任何主要特性是我既喜欢又了解如何添加的。当人们问这类问题时,他们脑中通常浮现的是多继承或RTTI这类特性,那么让我来告诉他们:缺少这些内容之一的C++将是一门低劣的语言。这两者我都广泛地使用,若没有它们,在需要使用它们的工作环境中很难找出更漂亮的解决方案。D&E里当然有这方面的例子与解释。

CP:事实上我感觉最需要改变的内容是虚函数。例如,我不很喜欢这个事实:一个虚函数可以在一个私有派生类中被重定义。这个函数不能被调用但却可被重定义,这多少破坏了私有继承的有用性与安全性。

说得更远一些,您可能还记得Sakkinen关于“C++的继承原则”的那些论文,他得出了几个很好的观点,我尤其欣赏其中一条:在更加严格的规则下,你不要非必要地扩展调用一个继承图中虚基类构造函数的能力。实际上,由于我理解C++中VBC(virtual base class,虚基类)现行规则背后的原因,我不得不在某种意义上认可他的观点,调用一个VBC的构造函数削弱了由中间类提供的封装能力。另一方面,经过多年的使用,我们了解了C++的强项与弱项,而Sakkinen的建议或许指出了C++的其他弱项,尽管考虑到“编程风格”时我对它们还有那么一些好感。

BS:基本上讲,我考虑这些问题纯粹是从学术角度出发,而没有考虑实际编程因素。设计一个恶意访问信息的构造函数是可能的,但编写一个初始化自身数据的构造函数基本上是无害的。此外,如果虚基类是public的话(我一直这样建议),所有类都应该知道它的存在并且必须调用其构造函数。这样的话,虚基类与其他基类就没有区别。当一个虚基类在某处被私有继承,在另一处又被公有继承时,如果继承体系最底层的类初始化这个私有虚基类的方式让虚基类作者感到惊讶的话,那么我猜想“由中间类提供的封装能力”就已经被削弱了。然而,倘若这就是某人最棘手的问题,那我们要真心祝福他了。

我认为“用一个私有函数覆写一个虚函数”或“覆写一个私有基类的函数”都不会引起问题。如果你把一个基类用作一个接口,此接口用户就无需关心其实现者(其派生类)如何实现之。一个派生类把它覆写的函数设为private,我感觉这是很易想象的,这么做正是为了确保使用此派生类只有通过预定的基类接口,并能防止进一步派生。如果一个基类为private,它仍然可以被其友元访问,或者也可通过它的派生类获得private基类的指针以应需要。例如,一个派生类可以返回它的基类接口作为一个执行系统级访问控制检查操作的结果:

class A
{
    virtual void f() ;
};

class B : private A
{
    void f(); // implementation
    A* get_A(Rights& r) { /* check rights */ return (*A)this; }
};

CP:另一方面,私有继承是不可传递的,因此下面这种情况下:

class A
{
    virtual void f() ;
};

class B : private A
{
    void h() { f() ; }
};

class C : public B
{
    virtual void f() ;
}

类A并非类C的一个接口,A::f()在C中不能被调用,却可以在C中被重新定义。我们只能说罪人是类C的实现者,他以类B的实现细节(“类B通过类A实现”这一事实)为基础设计自己的代码。一些人可能希望语言自身能够阻止这种做法……

BS:是的,这是一个糟糕的例子。然而,要想制定出一套规则以让所有糟糕的例子都变为不合法,同时处理好那些有人认为糟糕但也有人却认为对他们的工作至关重要的例子,却并非易事。一般而言,我反对那些并非出于实用目的而做的限制。我不把“正交性”作为一项主要的设计目标,但在没有任何选择“非正交”的头等理由的情况下,我当然倾向于选择“正交”。C++的访问规则就非常有正交性(包括命名规则、覆写规则等),而我没发现任何理由使它们不是如此。这些规则或许会让人们感到吃惊,但缺乏正交性的规则却必定会让人们吃惊。

CP:我理解您的观点,而且我很大程度上表示赞同。这就是我说“在考虑到‘编程风格’时这是一类良好的‘规则’”的原因。在特殊情况下类似的内容当然会非常有用(例如在复用一个没有源代码的库时),在那种情况下我们可以“违反规则”以完成工作,因为C++不是一门“母亲般”的限制性语言。

BS:我很希望C++捕捉出自程序员的逻辑错误的能力变得更强。毕竟,与完成等价工作的C代码相比,C++的许多特性确实有这种效果。然而,我认为不应以“现实问题的表达变得复杂化”为代价来换取安全性。这,再加上对兼容性的考虑,限制了让语言本身更加整洁所能采取的做法。对于专门的应用,我建议利用库使C++用起来更加安全。例如,如果某些人担心C数组没有范围检查,那他们应该使用提供范围检查的vector类。我自己多数情况下也是这样做,尤其为了调试方便。

CP:让我们再回顾一下C++……

BS:无论好坏,从C++初期开始我就一直保持对C高度兼容,而且标准委员会遵循我提出的“尽可能接近C但不要更接近”的原则。从语言技术的观点来看,C++中很多东西可以比现在更优秀 — 但那是不现实的。我从一开始就决定了兼容议题,并尽自己最大努力来容忍那些次要缺陷,只纠正了那些与类型系统相关的问题。另外的选择就是再创建一门“时尚”的语言:它在追随者眼里优美之至,而对于通过编程解决问题的绝大多数人来说,除了一个哈欠不会引起任何其他反应。就算没有C使C++与之兼容,我也会选择与另外某种语言兼容。我过去坚信 — 现在亦然 — 若我的时间花在发明另一种编写循环的方式上是一种浪费。

“并发”是一个不停浮出水面的议题。多数人喜欢某种形式的“并发”,而且希望看到C++对它提供直接支持。然而,没有任何单一形式的并发机制能够同时满足数量稍多一些的、真正需要并发机制的C++程序员之要求。操作系统编写者需要一种,数据库用户需要另外一种,而网络应用实现者又需要另外一种。因此,我决定让C++不含有明确支持并发机制的特性。需要某种形式的并发机制的人可以通过库对语言的扩展以获得支持(这是最可取的方式),他们也的确是这样做的。标准委员会在这个议题上也支持我。我们了解的具有吸引力的并发方案有多种,但没有一种可以同时为绝大多数C++用户服务。使用C++的领域范围之广确实令人吃惊。

美国计算机协会的第二次会议邀请我就编程语言历史写一篇文章(这个会议每15年开一次!)。针对那篇文章,有人问我关于C++我最大的失误是什么。在我看来“最糟糕的失误”这个头衔的唯一候选者即:我没能编制出一套可被接受的基础库并与1985年C++ release 1.0搭配发布。我的托辞是我不知道如何编写一个足够优秀的库。要想提供高效、灵活而且类型安全的容器,我需要模板机制。这个失误导致了现在各种设计哲学迥异、质量参差不齐、互不兼容的基础库混乱不堪的局面。

幸运的是,标准委员会能对一个卓越的标准库表示一致赞同。我们现在拥有了我未能写出的、在十年前我也不知道如何设计并实现的东西,这就是首先出自Alex Stepanov的作品 — 作为标准库主要组成部分的容器与基础算法框架。实际上它们与release 1.0发布前后几年我们对优秀库组件相关的原则和技术所进行的研究存在某种渊源,因此这个迟延并不是完完全全的浪费。

CP:如您所知,有些人提议在C9x中加入某些C++特性,例如对类的限制性支持。我对其中一些天真的做法还有印象,例如没有构造函数、赋值运算符重载等等。您对这种“新ANSI C”持何态度?

BS:这些特性在我看来的确天真幼稚,而且伴随的解释似乎反应出他们对“C++是如何在回应反馈过程中不断进化的”缺乏正确认识。我对一门语言应该做什么一直有一个整体的观念,但在这个观念内部,我认真地搜寻人们随语言进化反馈回来的意见,以根据现实的经验与需要来调整语言特性。

试图挑选出C++特性的一个小子集来打造“一门具备几乎全部C++威力但更简单的语言”,我认为这注定会失败。除非是根据实际经验十分谨慎地挑选,不然那些特性只能对一致编程风格提供部分支持,而一种特性往往会引至另外一种。因此,只有对“哪些设计和编程风格被直接支持”有一个全面的认识,并且在它的指导下进行特性添加,才能产生出一门一致的语言。

由我去试着告诉C社群他们应该如何标准化他们的语言并不合理。假如我这样做了,我的建议也许无论如何都不受欢迎,因为那些非常重视我建议的人无论如何都会使用C++编程。对于C,C委员会将会做出他们需要的举动,他们才是是对C核心社群最了解的人。任何与C++相兼容的扩展肯定是可能的。编程社群不需要另外一种不兼容的C方言。K&R C还没有消亡,目前的ANSI C将会长久存活直至另一套新标准发布,而C++中各种“过时”的内容在C++标准正式化之后也将继续存在。事情进展需要的时间往往比我们预想的乐于接受的时间长。C9x的新特性必将成为C与C++社群不稳定因素的另一个来源。

CP:谈起C++的后代,我免不了要提到Java……您认为它宣传鼓吹的效应有多大,您是否看到了Java的真正强处(如果它有的话)?我知道,作为一位语言设计师,您批评语言时十分谨慎小心,比如说“任何语言都有一个合适的小生境”,但您真实的感受是什么呢?

BS:Java有与C++相似的语法,但它是支持一种不同文化以及不同范围(相当狭窄)编程风格的一门与C++有着根本区别的语言。Java当然不是“在没有兼容限制下我就会设计出的类似于C++”的语言。现在人们的期望、Sun的营销金额以及与Web的集成把Java推崇至令人惊讶的地位。时间将会说明它如何作为一门通用语言而取得发展,时间还会告诉我们当多数程序员与管理者发现Java和(尤其是)Javascript在“安全性”上的严重缺陷时他们会如何反应。人们把编程语言的类型安全(type safety,这是正确的Java编译器已提供了的)与安全性(security)搞混了。安全性指的是确保系统完整性与秘密性(使用Java会对此造成严重威胁)。注重安全性的人士戏称Java为“制造病毒的语言”,并强烈建议我们使用不支持Java和Javascript的网络浏览器。回到编程语言议题:

C++
* 是一门更好的C
* 支持数据抽象
* 支持面向对象编程
* 支持泛型编程

在这些方面,Java仅含盖了面向对象这一部分,而且是利用与C++有着显著区别的方式实现的。

(译注:请各位不要误解,Java与Javascript完全是两回事,但都适用于Web编程。Java可运行于服务器端,如JSP、Servlet,也可下载至客户浏览器端,如Applet;而Javascript多下载至浏览器端运行。另外,也请读者注意Bjarne Stroustrup说这些话的时间是1996年)

CP:某些最新加入C++的内容是有用的,但它们属于细枝末节,例如explicit、mutable,再如新风格的转型操作这种“逃脱出C”的特性。您是否预见到未来会出现更多的基于设计的语言特性?比如说,在类似Annotated C++或Larch-C++这样的项目中可能存在些有价值的灵感火花:更着重于规格方面而减少停留在编码层级上的研究,或者学习某些加入更多语义的方法,例如让对象共享决策更加清晰明确。或者您在嵌入式、系统编程、性能要求严格的领域增强语言的意愿早已十分强烈?

BS:C++有向强宣告性的编程风格漂移的倾向。然而,一旦涉及语言的官方定义,语言与标准库的变化现在就不得不暂停,以给编译器实现者、用户、工具构建者以及教师等赶上来的机会。当然了,试验将会继续(尽管很可能并非由我进行),但我认为C++开发者社群最最需要的东西是“稳定”。目前C++在其使用领域是完整一致的,从现在开始,进一步的工作将会在子社群(例如学术界)中开展几年。

模板机制有多种多样的说明规格,我想多数人必定会对它的强大表示赞赏。例如,下面的概要代码定义了一个list,它的一份实现码可被所有类型的指针list共享:

// general list<T>:
template<class T> class list { /* ... */ };
// specialization for lists of void*:
template<> class list<void*> { /* ... */ };
// general list of pointers (implemented using list<void*>):
template<class T> class list<T*> : list<void*> { /* ... */ };

此处使用的特化机制在向用户提供单一通用接口的同时还(使用类型推导机制)提供可选的不同实现。其中一个重要的方面就是它强化了C++编程之宣告性天性,同时简化了用户接口并提高了运行时效率。标准库中的这些技术允许我们提供单一且通用的sort()例程,在实际例子中它比C标准库的qsort()快7倍。

CP:在95年5月号的《IEEE Computer》中,Wirth教授将C++称作“一门阻碍结构化思维和中规中矩编程的语言”。对此我不能表示同意,我也不能说Oberon 比C++更鼓励结构化与规范化,但在此处是否存在一些事实,让您乐意向纯化论者/学院派让步呢 — 他们必须在“因C++在现实世界中有用而教授它”与“因其与计算机科学教学中正式的、基于规范的方式相去甚远而不教授它”两者间做出选择。他们最终选择教授全面促进“契约编程”的Eiffel或“纯粹OO”的Smalltalk。

BS:Wirth教授素来不以有雅量称赞并非他亲自设计的语言而闻名,因此我不能说他的评价让我感到惊讶。另一方面,我认为他是断然错误的。对于优秀设计、工业规模的编程以及精准地考虑复杂的问题,C++都不失为胜任有余的工具。我猜此情此景正适合我对Simula和C的设计者为我构建C++提供了坚实的基础以及对他们纯粹的高尚人格表达感激之情。我还从许多其他语言身上吸取了很多东西。如果你知道观察哪里,你就能从C++中找到Algol68、ML、Ada以及BCPL的蛛丝马迹。许多伟大的语言就在你我身边。每个人都应该以精通多于一门语言为目标 — 这对编程语言和自然语言都适用。多一门语言会对一个人的世界观以及能力帮助极大。C++中很多东西可以更优秀。然而,现实使用的每种语言都是这样。即使那些声称为“纯粹”的语言也不例外。以我的经验看,C++在教学以及现实使用方面的问题都不严重。当然了,一个学生可能学不好,而一位老师采用的教学方法也可能让学习充满了不必要的痛苦。然而,这些情况确实发生在所有语言的身上。C++拥有能够适用于现实世界中不同应用领域的形形色色的问题的优势。学习更整洁的/更新的语言的很多安逸之处来自于其简化性,这种简化性迫使用户在遭遇到领域之外的另一种应用时,另外一门“整洁的”语言便成为一个合理的选择,因此不得不放弃原来的语言。当然了,这种情况对于C++用户也可能发生,但在某种程度上触及系统编程的所有领域中,这都很少发生。C++拥有整洁的子集,而其复杂性来源于人们草率地着手把玩一些需要更加深入、广泛理解的特性与编程风格(或称为“范型”)。在系统编程领域,“整洁”语言的用户往往不得不转而选择更低阶的“非整洁”语言 — 通常是C或C++。在我看来,C++应该在正式讲台上以大力强调概念的方式进行教授。

CP:很棒的观点,真的。尽管如此,有些人可能设想出一个更加整洁的子集,例如一个“C++学习版”:一个数组在用户没有特地请求的时候不会转型成一个指针,还有一些更多的具有相同精神的限制性因素。您是否认为这会是一种有用的教学工具(或许还会成为被C兼容性束缚较轻的人们的一种生产工具),抑或只不过是引发混淆的根源?

BS:事实上,我希望看到一个根本不用内建数组的“学习版C++”。学习者改用由教师提供的库(无疑是基于标准库的)中的vector、list和string类。这实现起来很容易,并且在一个教学环境中很容易强制实施 — 甚至无需任何编译器变动(只需降低对使用内建数组的评分即可)。同样,教师会发现很容易禁止使用显式转型操作 — 转型操作不应该出现在一个初学者的代码中。学习C++或其他语言的困难之处在于学习新的编程和设计技术,而非用来表达这些技术的语言特性。

人们被语言特性缠住的现象发生地太过频繁了。程序员缺少充足的背景来理解语言特性所支持的技术,而迷失在企图理解一门丰富语言的所有特性的尝试中,这种情况发生地也忒频繁了。值得注意的是:相比我们在现实世界应用开发工作中使用的开发环境、框架以及主要应用而言,C++甚至还要简单几个数量级。

C++与C密切且重要的关系伤害了C++的教学。因为C++(几乎)是C的一个超集,很多人以为他们在接触C++之前必须先学会(几乎)所有C特性和技术。其实并非如此,C++在许多方面的表现都优于C,而且C++标准库可以让学习者在一个提供了适用的vector、string等内容的环境中打好基础,再去面对C指针操作、转型操作、数组等复杂内容。C++可能成为(而且有些情况下确实是)一门用于教授编程、编程风格、设计等内容的优秀语言。若这一点成真,我们就可能取得一些进展,同时还可能避免许多无意义的语言战争经常浪费我们时间。

C++作为教学语言的一个强项是它将自身融入到讲授多种设计及编程技术之中。另一种替代方案就是讲授多种“更整洁”的语言来展示相同范围的技术。我认为断然错误的一种看法是:把当前的(通常是包含于单独的一门编程语言中的)一种设计和编程风格视为唯一正确的风格。一名专业程序员或计算机科学家最终会安然面对C++、Smalltalk、ML、Lisp和Eiffel(仅仅提及了少数几个)。当然了,罕有人能成为精通多于一门或两门或所有语言的专家,但最理想的状态肯定是熟悉所有这些内容,并随着时间推移在一些实际项目中尝试使用它们每一个。

CP:C++异常机制已被批评难以正确使用,请参阅Koenig在《C++ Report》上的文章:《为在使用异常机制时使指针更易管理而在标准库中引入auto_ptr的“必需性”》,以及《模板与异常规格之间的配合失谐》。而且异常机制实现起来似乎有些困难:Borland在用和不用异常处理的情况下连接DLLs时存在严重的问题。更不必提起关于“再审”的争论了,对此您的D&E已做了很好的叙述。因此,考虑到异常机制也会增加C++学习曲线的陡峭程度,您认为增加异常机制(尽管已存在于C++中)是否划得来呢?

BS:每一项新特性初次出现时都被认为是难于使用、代价高昂的,有些人还认为没必要用它们。许多“问题”却表明:这些问题几乎都不是真实程序中的实际问题。我认为异常机制极大简化了我的代码。就像所有真正有价值的特性一样,异常机制要求某种新思路以及某种组织代码的新方式(若非如此,这项特性又如何成为一项重大的改进呢?),我认为它的价值确实非比寻常。我认为所谓的“异常与模板之间的配合失谐”是虚假的。提供异常机制是为了构建针对错误情况的防火墙。也就是说,你选择一个明确的接口来规定只允许全部错误情况中的一个子集通过。几乎所有模板都不会成为防火墙的优秀候选者。模板机制是特意为与用户定义类型交互而设计的,而只要你稍有判断力,你就不会试图直接通过紧密混杂的代码来构建一个防火墙。如果那算是一种配合失谐的话,那便是吧。然而,我只将它视为概念的独立。它们做不同的事情,而且它们可以被结合使用。

CP:在某种程度上,模板机制与异常规格存在一种配合失谐,因为模板以特殊的方式来使用实际参数,这致使无法声明一个正确的异常规格(exception specification),甚至看上去简单无害的代码(例如一个用于比较的模板函数)也不例外。总的来讲,我认为,若说异常机制存在某种负面效应的话,那就是它让本来看上去无害的代码变得不那么清白了。

BS:实际上,许多这类“看上去无害的代码”绝不是那么清白。这类简单的代码往往潜伏着大量未被检查的错误情况,并且不得不遭受C风格setjmp/longjmp的迂回处理。因此,异常机制将注意力集中在许多人容易忽略但其复杂性早已存在的问题上,这个问题并不是异常机制引入的。我认为把异常规格加到模板函数上是不合理的 — 至少对于不那么常见的模板函数是这样。其原因 — 正如你正确指出的 — 所有可能被抛出的异常既包括模板抛出的异常,又包括模板参数抛出的异常。这便是我说模板通常不能作为防火墙的优秀候选者的原因之一。我不相信能够确保每一小段代码都具备防弹功能。取而代之的是,我更喜欢以多个子系统的方式来表达系统,并把子系统的边界作为防火墙,那里就是我使用异常规格之所在。

CP:一个看起来仍然薄弱的C++领域是对象的持久化……一定数量的库或工具已经出现,但在多数情况下你终将需要一个自定义的预处理程序或者某个手工编写的函数。RTTI似乎是一个有前途的发展方向,但除非出现了某种标准,它也只不过是另外一种不可移植的扩展罢了……

BS:我根本就不认为持久化属于一门通用编程语言的范畴。不同的人所需要的持久化数据的种类不同,他们对性能、可靠性、访问控制、查询的特性等方面的要求差异很大。我认为这个问题适合留给库供应商和数据库供应商。我倾向于限制使用预处理程序和额外的语言工具,但有时是需要它们的。在我看来,一门编程语言不应该试图含盖一切,它无论如何也不可能同时处理好一切。而且你说的没错,RTTI可能会对多种持久化和数据库服务实现者们有相当大的帮助。

CP:C++是现在最成功语言之一,身为它的设计者,您对学术界里无数的人不时吵闹着创造另外一门语言有何建议?

BS:以问题作为导向。一门成功的语言是对一系列已被良好理解的问题的一套解决方案,而不能只一味迎合目前评判一门编程语言看上去是否时髦的标准。如果你没遭遇到一个用任何现有语言都无法合理解决的问题,那就不必考虑再设计一门语言。语言设计是一个失败率几近100%的领域。如果有替代方案的话,任何理智的人都不会涉足此领域。因此,先找到没有合理解决方案的严重的编程问题,然后尽努力避免陷入到语言设计中去。如果你不得不设计一门新语言,尽可能地对现有语言施行“拿来主义” — 同时要心存感激。准备好尝试失败,并准备迎接为了战胜成败几率不均所要做的数量惊人的工作。

CP:另一种最成功的语言是Visual Basic。某些人认为它实现了OOP/C++的承诺,确切地说即大量可插接的组件、真正的复用,但可能是以某种程度的非工程化为代价。把不同C++编译器协同工作能力的实现留给第三方产品,例如SOM,而不是标准的一部分,您认为这样做正确吗?当然任何二进制标准都会限制编译器编写者的自由,不过任何标准化议题都有这个特点。可以放弃对多继承的支持以便榨取出某些性能上的改进,但这并非把多继承从C++中移除的一个好理由。为什么二进制标准会这么不一般呢?(当然了,二进制标准只不过是迈向“真正的”软件组件的第一步而已)

BS:C++实现了自己的承诺。不要盼着它会去迎合所有语言和系统的大肆吹嘘,说自己是面向对象的或者其他什么东西。C++是一门编程语言,而不是一种模块描述语言或一个操作系统。像其他任何语言一样,它不可能成为每一个人的一切。你可以用C++来构建“可插接的组件”,但那不是C++的首要目标(并且需要做些工作)。编译器间协同工作是一个难题。通过大量的工作在互相竞争的组织之间达成大量的协议,以这种方式甚至能实现让不同编译器编译的C程序片段协同工作,但人们对此通常并不赞赏。那些协议必须包括函数调用次序、数据布局、浮点数算术的细节等方面。C++要做到那一步比C难,但并非难很多,因为几乎所有的难题都是政治上的而非技术上的。多继承议题与任何二进制标准以及C++编译器协同工作议题都是毫不相干的。我认为SOM(至少其早期版本)中没有多继承只不过反映出它的最初设计者对Smalltalk和Objective C的一种倾向。在C++这种依靠静态类型检查接口的语言中,某种形式的多继承是不可或缺的。不然的话就会导致矫柔造作的代码或不安全的接口,或兼而有之。

CP:您有没有什么新概念、想法或者特性考虑加入到“下一代C++”中并且乐意向我们预示?(我明白您想让C++在一段时间内保持稳定,但我猜那不会妨碍您考虑改进,可能是对已有特性的某些实现议题的进一步改进)

BS:我的感觉是,当谈及编程语言时,人们总是用空话去应酬实验,而且试图把这个领域作为数学或哲学的一个分支来看待。然而,我认为下一代C++应该来自于现实应用中的实际问题,并且来自于实验,而非来自对已有语言的思考与打磨。我发现描述我已完成的工作和一些我部分理解的东西比起试着预知未来要容易得多。我喜爱科学幻想,但不是在它伪装成技术性文章的时候。可是,在我们的领域中,我的确感到“真正的信徒”太多而实验主义者太少。为了改进我们的电脑系统,我们必须拥有大量优秀的实验以及海量的可靠数据。从它们身上获取睿智才能让我们判断出真正的问题是什么并弄清如何解决它们。而实情往往是这样的:我们只是无所事事地对我们的感受、观点还有理论进行哲学化的探讨,却没有设法取得实际进展。

-完-