最近C++/CLI成了国内程序员关注的焦点,原因是它的开发人之一Stan Lippman来中国开技术大会并全力推介它,而且《程序员》杂志刊登了孟岩老兄对此人的专访,于是软件界一时群情激昂、人声鼎沸,各种说法也是不绝于耳。此专访的节选被放在孟岩自己的BLOG上,后头跟贴相当多(恐怕有上百条),不少人流露出对C++/CLI的反感甚至鄙夷,更有过火者对Stan Lippman本人也是大肆挞伐,说他是微软的无耻鼓吹手云云。我对C++/CLI没有研究,也没有在.NET上做过开发,对它们的了解都是源于技术大拿们的介绍,但是我仍然想谈谈自己的看法(不懂也敢说话?呵呵,姑妄听之吧)。
在选择开发用语言上,我是一个非常保守的程序员,我最中意的语言是C/C++与汇编,开发工具用的最多的是Visual C++。顺便说一句,我曾经从事的并且最感兴趣的领域是游戏开发。从微软宣布.NET以来的相当长一段时间里,我对它都是报着极大的抵触情绪,认为它是一个吞食一切的庞大怪物,丑陋、臃肿与野心勃勃。至于C#,我更是毫无接触便认定它是个怪胎。我想,在中国或许有不少人和我一样有这种盲目敌视的心态吧。这是为什么呢?现在看来,最重要的原因无非一条,那就是微软的技术更新步伐越来越快,就算是保持距离跟随其后对不少人来说也是有心无力,所以我们由无能逐渐害怕,而由害怕又生出了仇恨。就像满清末期抵死反对维新的大臣一样,只不过他们有能力扼杀改革,而我们没有。
最近一段时间,由于希望能做一点将形式化方法与面向对象技术结合的研究我开始了对Eiffel以及契约式开发方法(Design by Contract)的学习。国内听说过Eiffel的人可能不多,但是听说《Object-Oriented Software Construction》(《面向对象软件构造》)这本书的人应该不少。该书曾荣获1997年JOLT大奖,它详细阐述了面向对象开发方法的各个方面,对许多重要概念做了极为细致深入的分析,而Eiffel就是书中作者(Bertrand Meyer)带领读者发展出的一套运用在软件开发全过程中的面向对象标记法。可以把Eiffel看成一门面向对象的编程语言(虽然它不仅仅是一门编程语言),在这门语言中最重要的是引入了“契约”(contract)的概念并建立了直接支持此概念的语言机制。了解形式化方法的朋友肯定都知道前置断言(precondition)、后置断言(postcondition)、不变式(invariant),而contract就是Eiffel中它们的对应物。在人类社会中契约具有法律效力,它能明确地规定签约方的权利与义务,从而为营造一个权利与义务平衡,理性而稳定的社会提供基础。同样,契约可以通过明确程序中各种操作的权利与义务来精确地刻画它们的语义,由此构造高质量的软件才有了坚实的土壤。在学习了契约式开发思想之后我多么希望也能将它应用在其它语言中啊,尤其是C/C++。可是C/C++并没有直接支持contract的机制。孟岩曾经撰文(《Design by Contract原则与实践》的附录)介绍如何在C++中用assert来模拟它,但是局限性太大,很多关键的思想无法运用。就在昨天我看到一篇Bertrand Meyer于2000年写的文章"The significance of .NET" ,说他们已经开发出了一个基于.NET的叫Contract Wizard的软件,它能让你为.NET组件(无论是用什么语言写的)中的类以及类方法加上preconditions, postconditions 和class invariants,就象Eiffel中能够做的一样,最关键的是在此过程中你无需这个.NET组件的源代码,Contract Wizard直接对编译过的组件进行操作,更改它的metadata,然后生成一个新的带有契约的.NET组件。这就是说,以后我可以将我所需要的所有组件(不管有否源代码,不管用什么语言编写)都用与Eiffel中一致的contract武装起来,从而大大提高软件的质量与安全。很神奇,不是吗?而这一切都拜.NET中自描述的组件机制所赐。事实上Meyer的这篇文章还介绍了.NET的其它方面,比如语言间的互操作性(Language interoperability),这让程序员可以继承与扩展用不同语言写成的类;比如对象模型VOS(Virtual Object System),Meyer称之为微软“努力为各种语言定义的一个通用而适当的基础”,“而这个基础将在不同语言间起着桥梁的作用”(it is an attempt to define a suitable common base that can serve as a bridge between all these languages, and others.);比如虚拟机,微软一开始就全力提高MSIL(MicroSoft Intermediate Language)在CLR上的执行效率,这可从QUAKE2的.NET版本没有明显的效率损失得到验证。抛开对微软的偏见站在纯粹的技术角度来看,.NET难道不是一个体现了远见、活力与趣味的平台吗?而且随着ECMA(European Computer Manufacturers Association)将CLI标准化,它还成为了一个开放的平台,著名的Mono项目就是其在Linux上的实现。有的朋友可能会说不要拿技术权威的文章尤其是外国权威的英文文章来吓唬人。我不会狐假虎威,但是对于一个在软件领域有如此造诣的大师,如果他所说的是理性、客观且负责任的,我为什么不能相信他,又为什么不能推荐给大家,让大家能有更多的思考?
C++/CLI是一个积极的尝试,在我看来它期望的是:在最大限度地利用.NET提供的各种先进功能的同时又最大限度地保持C++的编程模型。这是一件好事,尤其对那些喜欢C++而又必须在.NET平台上工作的人来说更是如此。讨厌C++/CLI的朋友,你们也别太过激动,毕竟你们仍然有选择Native C++的权利,没有人强迫你们。就我来说,由于游戏开发的要求,在相当长的时间里我仍然会固守C/C++以及ASM的阵地,但是同时我也极有兴趣探索C++/CLI这门新鲜的混血语言。即便是在游戏开发领域,.NET平台的许多技术也值得学习,事实上早有游戏运用了与.NET相似的技术。比如Unreal,它的逻辑部分便是由UnrealScript脚本语言写成,而这种脚本则运行在提供了多线程以及内存回收机制的虚拟机上,并且它也能与C/C++在源码级进行良好的互操作(比如在脚本中使用由C++写的class)。虽然这些技术的发展已行之有年,但.NET无疑是一个全新的且极有价值的借鉴对象。
或许微软有许许多多霸道的做法,但是近年来它表现出的创造性却不得不令人佩服。我们可以很情绪化地咒骂C++/CLI,咒骂.NET,咒骂微软,甚至咒骂被微软雇佣了的Stan Lippman,可是我们失去的是什么呢?在上面提及的"The significance of .NET"这篇文章中,Bertrand Meyer虽然对.NET总体上持肯定态度,但是仍然批评了它的一些技术选择,比如继续提供重载overloading机制(Meyer一贯反对重载并撰有多篇文章阐述背后的理论,可惜他的真知灼见不是主流),可是这种有分量的技术批评却鲜见于我们的讨论中。我们在一次次的谩骂中发泄了心中的不满,但同时也在这一次次的谩骂中丧失了独立探索、实事求是、理性怀疑的科学精神。没有了这种精神,我们还有什么资格被称为“程序员”呢?
本文地址:http://com.8s8s.com/it/it472.htm