Programming 版 (精华区)

发信人: zhangyan (塑料脑袋镀浆糊), 信区: Programming
标  题: C++的不足之处讨论系列(二)
发信站: 哈工大紫丁香 (2001年04月29日09:35:25 星期天), 站内信件

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. Schwartzbac
h, Object-Oriented Type Systems, Wiley 1994)
    
    C++中的一个主要问题就是:对于程序的分析过程被编译器(工作于开放式环境下的假
设)和链接器(依赖于十分有限的封闭式环境下的分析)给划分开了。封闭式环境下的
或是全局的分析被采用的实质原因有两个方面:首先,它可以保证汇编系统的一致性;
其次,它通过提供自动优化,减轻了程序员的负担。
    
    程序员能够被减轻的主要负担是:设计父类的程序员不再需要(不得不)通过利用虚拟函
数的修饰成份(virtual),来协助编译器建立起vtable。正如我们在“虚拟函数”中所
说,这样做将会影响到软件的弹性。Vtable不应该在一个单独的类被编译时就被建立起
来,最好是在整个系统被装配在一起时一并被建立。在系统被装配(链接)时期,编译
器和链接器协同起来,就可以完全决定一个函数是否需要在vtable中占有一席之地。除
上述之外,程序员还可以自由地使用在其他模块中定义的一些在本地不可见的信息;并
且程序员不再需要维护头文件的存在了。
    
    在Eiffel和Object Pascal中,全局分析被应用于整个系统中,决定真正的多态性的函
数调用,并且构造所需的vtable。在Eiffel中,这些是由编译器完成的。在Object Pas
cal中,Apple扩展了链接器的功能,使之具有全局分析的能力。这样的全局分析在C/Un
ix环境下很难被实现,所以在C++中,它也没有被包含进去,使得负担被留给了程序员。

    
    为了将这个负担从程序员身上移除,我们应该将全局分析的功能内置于链接器中。然而
,由于C++一开始的版本是作为一个Cfront预处理器实现的,对于链接器所做的任何必要
的改动不能得到保证。C++的最初实现版本看起来就像一个拼凑起来的东西,到处充满着
漏洞。【译者认为:这也太过分了吧:)】C++的设计严格地受限于其实现技术,而不是其
他(例如没有采用好的程序语言设计原理等),因为那样就需要新的编译器和链接器了
。也就是说,现在的C++发展严格地受限于其最初的试验性质的产品。
    
    我现在确信这种技术上的依赖关系(即C++依赖于早先的C)严重地损害了C++,使之不
是一个完整意义上的面向对象的高级语言。一个高级语言可以将簿记工作从程序员身上
接手过去,交给编译器去完成,这也是高级语言的主要目的。缺乏全局(或是封闭式环
境下的)分析是C++的一个主要不足,这使得C++在和Eiffel之类的语言相比时显得十分
地不足。由于Eiffel坚持系统层次上的有效性及全局分析,这意味着Eiffel要比C++显得
有雄心多了,但这也是Eiffel产品为什么出现地这么缓慢的主要原因。
    
    Java只有在需要时才动态地载入软件的部分,并将它们链接起来成为一个可以运行的系
统。也因而使得静态的编译期间的全局分析变成不可能的了(因为Java被设计成为一个
动态的语言)。然而,Java假设所有的方法都是virtual的,这也就是为什么Java和Eif
fel是完全不同的工具的一个原因。关于Eiffel,可以参见于Dynamic Linking in Eiff
el(DLE)

--
※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: 电信来客]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:3.417毫秒