`
helloyesyes
  • 浏览: 1280095 次
  • 性别: Icon_minigender_2
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

被误解的C++——法国大革命

阅读更多

法国大革命

Linus大骂C++”事件闹得沸沸扬扬。无论是技术,还是人品,都是谈论焦点。各有各的看法,读起来也颇有趣味。可是,人们争吵的同时,却很少想到用一些实在的论据来证明自己的观点。范例代码也好、严格的分析和论证也好,对于有益的争论而言,都是必不可少的。绝大多数人都泛泛地,凭着主观臆断发表言论。我看到的唯一例外是pongba的文章《为什么C++。里面有理有据,层层推进。只是通篇英文,对于只知凭口才争论的人而言,是不会有耐心去细读的。

当前语言的论战,让我想起了一段历史——法国大革命。由于社会压迫和不平等,巴黎人发动起义,攻占巴士底监狱,推翻了路易十六。之后,便陷入了混乱。大量政治投机分子混迹于革命者中,想借此捞取政治利益。无政府主义充斥社会,尽管砍下了路易十六全家的脑袋,也未能使人们的生活发生改变,承诺过的平等和自由也未见踪影。然后,保皇党打回来,革命失败。接着革命者卷土重来,然后又是保皇夺取政权。随后出现了拿破仑,成为全民的偶像。拿破仑最终称帝,并且因战败被流放和毒杀。此后,执政者走马灯似的换来换去。民众的态度逐渐变成了:我不管你是贵族还是平民,保皇还是倒皇,独裁还是民主,赶快结束混乱和战争吧。

大革命前,民众受尽了压迫,渴望自由和平等。但革命后,无政府状态的自由和民主,以及带来的混乱,却又不是他们所期望的。因而当王朝复辟,民众也未表现出什么敌意。自然复辟也并未给民众带来好处,继续的革命,又成了人们渴望的事情。如此反复,以至于对拿破仑的称帝,也未表现出任何不满。

回过头看看编程语言的发展,何尝不是如此呢?从最初没有语言,到机器语言和汇编语言,编程一直是专家的工作,语言也是少数精英的专有品。随后高级语言出现,人们可以用近似人话的东西指挥计算机。C语言的出现,使得系统编程有了非常合适的工具。同时,人们也发现C语言同样也能用于其他类型的开发。于是,C语言成了应用最广的语言。然而,人的本性促使人们对于C语言的很多缺陷产生不满,诸如抽象能力不足、资源管理困难等等。为此,C++被发明了,人们获得了C语言一样的灵活性,也获得了更强大的抽象能力。但是,就像大革命后的民众一样,人们对于C++的复杂性表达出不满。人们开始畏惧原先热心追捧的OOP、模板等等。有的人试图回复到C,那种简单的自由;有的人则追随Java等,试图通过抛弃灵活和自由,来换回简单。

对于限制和自由,简单和复杂,原本就是“仁者见之谓之仁,智者见之谓之智”。很难有定论。但我们祖先的智慧,对此也有深刻的理解。老子曰:“福兮祸之所倚,祸兮福之所伏”。于是,限制和自由,简单和复杂,实际上是你中有我,我中有你。限制有时也会提供一些自由,比如强类型化,是一种限制,但强类型却能阻止我们进行错误的类型转换,从而使得我们在使用类型和类型的对象时,不必如履薄冰。

再比如,C++中的类型转换操作符,在默认情况下执行隐式的类型转换:

class X

{

public:

operator int();

};

X x;

int a, b, c;

int a=b+x; //由于疏忽,c错打成了x(在键盘上它们相邻)。这里没有编译错误。

C++提供这种操作符,则提供了一个类向另一种类型的转换的自由,但却很容易造成难以发现的错误,使得我们类型转换操作符的使用受到很大的限制。

同样,简单和复杂也总是辩证的。有时复杂会造成简单,而简单也会造成复杂。

复杂造成简单的案例在C++中随处可见,最典型的当属STL。设计和开发STL运用了C++最复杂的特性,但却使我们得以以最简单的方式编程:

// in C

DIR* dir = opendir(".");

if(NULL != dir)

{

struct dirent* de;

for(; NULL != (de = readdir(dir)); )

{

struct stat st;

if( 0 == stat(de->d_name, &st) &&

S_IFREG == (st.st_mode & S_IFMT))

{

remove(de->d_name);

}

}

closedir(dir);

}

// in C++

readdir_sequence entries(".", readdir_sequence::files);

std::for_each(entries.begin(), entries.end(), ::remove);

And it’s even simpler in C++09:

// in C++09

std::for_each(readdir_sequence(".", readdir_sequence::files), ::remove);

此案例引述自pongba的《为什么C++》。但对于从未了解过STL的人而言,却又像天书那样难懂。学习STL的基本概念的使用,对于很多人而言,是非常“复杂”的事。可一旦理解了,学会了,这一切又是那样单纯和直观。

所以,每当你有一口咬定某某东西简单或复杂时,先想想我们老祖宗的话:“福兮祸之所倚,祸兮福之所伏”。

让我们再回到法国大革命上来。民众希望得到平等和自由,但却又不希望有什么付出,自己的生活受到什么影响。且不说这种思想的狭隘性和利己性,这都是现实存在的,也都有它的合理性。为此,睿智的人只会寻找一种温和的中间路线,以满足中间的大部分民众。

但是,一旦大革命开始,社会走向平等和自由的趋势已经难以挽回。同样,尽管人们会从极端追求性能和自由的C摆向极端追求简易和限制的Java,或者再摆回来,走向更强大的抽象体系之路也不会回头。最终还是会逐渐趋向于一种平衡的中间状态。用控制论来描述,这是一个收敛的负反馈系统。而用中国古代哲学来描述则是:“反者道之动,弱者道之用”。

C++只是这个震荡过程中的一个开拓者。未来肯定会有很多超越C++的语言出现。但是,技术的进步已经无法挽回,我们也无法倒退到史前时代,我们只能向前进。但我们必须记住的是,新的强大的语言,必须象C++一样同时兼顾性能和抽象,但却没有C++的缺陷。(这种语言不会是简单的,但不会象C++那样复杂,因为C++大多数复杂性都来源于它的缺陷。)。这种语言应当能够以接近数学的形式描述一个问题或算法(依赖于抽象),但却能最大限度地保证运行的效率(依赖于性能)。C++在这些方面做了很多尝试,而且相当成功。但也为此付出了巨大的代价:复杂性、缺陷、难学等等。但我们不能以此认为C++的路走错了,应该走回头路。我们所应该做的,是认清C++的优势和缺陷,汲取营养,为未来更完善的语言做好准备。(我想更完善的语言,不大会像C那样简陋,象Java那样愚钝吧。当然,也不会像C++那样复杂和充满缺陷)。或许真的没有哪种单一的语言能够达成这个目标,那也可以采用“语言族”的形式(就像自动步枪族那样),以一族具有共同语法基础、编程模型,但又有各自特长的语言共同实现这一理想。

另外,我还想强调一点:如何看待复杂性和难学性。复杂性和难学性有很多的来源。有的来自能力的扩展,比如,一旦引入OOP,那么自然必须面对类、对象、成员、继承等等复杂的概念。这是必不可少的。如果认为这种复杂性和难学性应该消除的话,那么这就相当于认为我们应该放弃电而改用火把和蜡烛。

另一些复杂性和难学性来源于语言的缺陷。这种复杂性是不应该存在的,是应该消灭的。当然这是做不到的。没有任何一种语言是完美的,没有缺陷的。我们应该以积极的姿态来看待语言。当我们一味地争论一种语言的什么什么不是,自然很难从中学到有用的东西,也更难从中获得好处。我们可以比较语言,但不应该争论语言。

最后,请注意,所有争论语言的出发点通常都是狭隘的,局部的。C语言的程序员喜欢以底层开发的要求强调语言的特性;Java程序员则喜欢以高层的应用开发的要求来评价语言。但是,他们似乎喜欢把软件开发的范围圈定在各自工作的范围内,来阐述某某语言的不足。可软件开发真的只有这些吗?要么最高层,只追求软件组装的简便性;要么最底层,只追求直观的数据表达和运行性能?是否在存在一些领域,既需要很好的性能,但不一定像实时系统那样风驰电掣;又需要长期的综合开发效率,但不一定象单一项目那样只抓现钞?

对于最后一个问题,我的答案是肯定的。诸如数据库服务器、各类应用服务器、搜索引擎、图像处理和视觉处理、操作系统的上层服务组件、数据分析和处理等等。这些领域的共同特性,都是既有很高的性能要求,满足苛刻的运行时间要求;又有足够复杂性,需要更强大的抽象能力来提高开发效率。而且,这些领域的软件都规模庞大,结构复杂。同时又需要长期发展,并且不断扩充,以获得更大的技术优势和市场优势。这样的软件项目实际上对开发语言的综合能力提出挑战。对语言运用成本的考核,不仅仅局限在单一周期的开发过程中,还需要包括所有迭代周期的总体成本。C++尽管算不上完美的语言,但却是在这些方面综合能力最强的语言。而对于这些项目而言,其高附加值足以抵消C++人员费用方面的成本。况且在充分运用C++的抽象能力后,可以获得最低的产品扩展成本,有利于产品长期的发展。

如果仔细地考察一下业界,我们会发现,没有任何一家主流的厂商声称C++过时。表面上看,象Sunms等公司,似乎正在积极地“反C++”。但是,他们实际上却是C++的积极使用者。(象他们这么积极地使用,怎么才能让C++消亡啊)。他们都认真地开发出很好的C++编译器,同时都积极参与C++0x标准的创建。他们的表现给人以一种“生怕被落下”的感觉。这一方面是因为他们有大量的C++代码存在,另一方面他们也充分认识到C++在软件开发中的作用。更重要的是,他们把C++看作一种未来。JavaC#或许能够满足他们眼前的利益,但从长远来看,人们善变的需求和品位,使这些语言不足以长期维持地为他们提供统治地位。而未来的C++则不仅仅为他们提供一种很好的软件开发的工具,或许有可能使得他们借以牟取某种商业上的利益也未可知。

C++有很好的基础(拜C所赐,所以C++程序员对C通常都心存感激,不愿意对C恶言相向),所以未来有很大的扩展和改进余地。它的生命力是强大的和持久的。每种语言都将没落,现在我们不会看到C++的结局,我们这辈人或许能够目睹C++的兴衰。希望人们能够真诚和认真地对待这样一种语言。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics