CSDN博客

img cber

C++的不足之处讨论系列(二)-- 全局分析

发表于2001/4/28 22:47:00  1409人阅读

分类: C/C++

以下文章翻译自Ian Joyner所著的
《C++?? A Critique of C++ and Programming and Language Trends of the 1990s》 3/E【Ian Joyner 1996】
原著版权属于Ian Joyner,征得Ian Joyner本人的同意,我得以将该文翻译成中文。因此,本文的中文版权应该属于我;-)
该文章的英文及中文版本都用于非商业用途,你可以随意地复制和转贴它。不过最好请在转贴时加上前面的这段声明。
如果有人或机构想要出版该文,请最好联系原著版权所有人及我。

另外,该篇文章已经包含在Ian Joyner所写的《Objects Unencapsulated 》一书中(目前已经有了日文的翻译版本),该书的介绍可参见于:
http://www.prenhall.com/allbooks/ptr_0130142697.html
http://efsa.sourceforge.net/cgi-bin/view/Main/ObjectsUnencapsulated
http://www.accu.org/bookreviews/public/reviews/o/o002284.htm

Ian Joyner的联系方式:
 i.joyner@acm.org
我的联系方式:
 cber@email.com.cn

译者前言:
 要想彻底的掌握一种语言,不但需要知道它的长处有哪些,而且需要知道它的不足之处又有哪些。这样我们才能用好这门语言,避免踏入语言中的一些陷阱,更好地利用这门语言来为我们的工作所服务。
 Ian Joyner的这篇文章以及他所著的《Objects Unencapsulated 》一书中,向我们充分的展示了C++的一些不足之处,我们应该充分借鉴于他已经完成的伟大工作,更好的了解C++,从而写出更加安全的C++代码来。

C++的不足之处讨论系列(二)

全局分析

 【P&S 94】中提到对于类型安全的检测来说有两种假设。一种是封闭式环境下的假设,此时程序中的各个部分在编译期间就能被确定,然后我们可以对于整个程序来进行类型检测。另一种是开放式环境下的假设,此时对于类型的检测是在单独的模块中进行的。对于实际开发和建立原型来说,第二种假设显得十分有效。然而,【P&S 94】中又提到,“当一种已经完成的软件产品到达了成熟期时,采用封闭式环境下的假设就可以被考虑了,因为这样可以使得一些比较高级的编译技术得以有了用武之处。只有在整个程序都被了解的情况下,我们才可能在其上面执行诸如全局寄存器分配、程序流程分析及无效代码检测等动作。”(附:【P&S 94】Jens Palsberg and Michael I. Schwartzbach, Object-Oriented Type Systems, Wiley 1994)
 
 C++中的一个主要问题就是:对于程序的分析过程被编译器(工作于开放式环境下的假设)和链接器(依赖于十分有限的封闭式环境下的分析)给划分开了。封闭式环境下的或是全局的分析被采用的实质原因有两个方面:首先,它可以保证汇编系统的一致性;其次,它通过提供自动优化,减轻了程序员的负担。
 
 程序员能够被减轻的主要负担是:设计父类的程序员不再需要(不得不)通过利用虚拟函数的修饰成份(virtual),来协助编译器建立起vtable。正如我们在“虚拟函数”中所说,这样做将会影响到软件的弹性。Vtable不应该在一个单独的类被编译时就被建立起来,最好是在整个系统被装配在一起时一并被建立。在系统被装配(链接)时期,编译器和链接器协同起来,就可以完全决定一个函数是否需要在vtable中占有一席之地。除上述之外,程序员还可以自由地使用在其他模块中定义的一些在本地不可见的信息;并且程序员不再需要维护头文件的存在了。
 
 在Eiffel和Object Pascal中,全局分析被应用于整个系统中,决定真正的多态性的函数调用,并且构造所需的vtable。在Eiffel中,这些是由编译器完成的。在Object Pascal中,Apple扩展了链接器的功能,使之具有全局分析的能力。这样的全局分析在C/Unix环境下很难被实现,所以在C++中,它也没有被包含进去,使得负担被留给了程序员。
 
 为了将这个负担从程序员身上移除,我们应该将全局分析的功能内置于链接器中。然而,由于C++一开始的版本是作为一个Cfront预处理器实现的,对于链接器所做的任何必要的改动不能得到保证。C++的最初实现版本看起来就像一个拼凑起来的东西,到处充满着漏洞。【译者认为:这也太过分了吧:)】C++的设计严格地受限于其实现技术,而不是其他(例如没有采用好的程序语言设计原理等),因为那样就需要新的编译器和链接器了。也就是说,现在的C++发展严格地受限于其最初的试验性质的产品。
 
 我现在确信这种技术上的依赖关系(即C++依赖于早先的C)严重地损害了C++,使之不是一个完整意义上的面向对象的高级语言。一个高级语言可以将簿记工作从程序员身上接手过去,交给编译器去完成,这也是高级语言的主要目的。缺乏全局(或是封闭式环境下的)分析是C++的一个主要不足,这使得C++在和Eiffel之类的语言相比时显得十分地不足。由于Eiffel坚持系统层次上的有效性及全局分析,这意味着Eiffel要比C++显得有雄心多了,但这也是Eiffel产品为什么出现地这么缓慢的主要原因。
 
 Java只有在需要时才动态地载入软件的部分,并将它们链接起来成为一个可以运行的系统。也因而使得静态的编译期间的全局分析变成不可能的了(因为Java被设计成为一个动态的语言)。然而,Java假设所有的方法都是virtual的,这也就是为什么Java和Eiffel是完全不同的工具的一个原因。关于Eiffel,可以参见于Dynamic Linking in Eiffel(DLE)

0 0

相关博文

我的热门文章

img
取 消
img