作者:孟岩 来源:CSDN博客 酷勤网收集 2007-12-04
(本文是发表于2006年第6期《程序员》杂志的同名文章的节选。全文请见杂志)
C语言天生就与开放结缘。C最初是作为UNIX的系统编程语言而流行起来的,而UNIX可以被认为是第一个产生重大影响的“开源”软件。随着UNIX的流行,C语言逐渐被人们认识和喜爱。很快的,在各个平台上C语言都成为了流行的甚至是统治性的程序设计语言。大约到1980年代中期,C已经成为人类历史上第一种工业级程序设计世界语。很多人都知道,正是C这样一种世界语的出现,才使开源运动的出现和最初发展成为可能,从这个意义上讲,说C语言是开源运动之母并不十分过分。但人们不太能够认识到的是,事实上C语言统治地位的获得,却也是早期开放软件运动的直接结果。多数人在回顾这段历史的时候,经常会感染中国文人的不严肃的浪漫主义史观,喜欢把C语言的成功归结为汉高祖斩白蛇般的天赋神格,描述为遥想公瑾当年,谈笑间樯橹灰飞烟灭的轻飘飘。然而如果我们对历史作一些细致的调查,我们会发现C语言绝非有什么天命,而只不过是幸运地扒上了早期开放运动的快车而已。在C语言“小人乍富”的那几年,也还有其它不少程序设计语言具有高性能、可移植、系统开发能力强的特点,决不是只有C骨骼特异,貌若天仙。如果Pascal也能借助一个像UNIX那样的开放的幽灵在欧美大学校园里徘徊,那么我们今天很可能要把begin和end直接映射到键盘上。如果IBM不是在1970年代极端保守地把一种叫做PL/X的语言牢牢地限定在自己的研究所里,也许整个程序员社群的图腾就不是贝尔试验室的那两个大胡子,而是小沃森实验室里的IBM某院士。事实上,C语言的成功,更须拜开放软件运动之时势所赐,或者更确切地说,C与开放软件是一对共生体,它们相互扶持,相互成就,共同成长兴旺,共同创造历史。
根深自然叶茂。今天C语言体系内所拥有的开放资源,无论是数量和质量,还是丰富性、多样性、创新性、可靠性、重要性,都是其它任何开发技术体系所无法望其项背的。丰富对于开发者是好事,但对于写资源介绍性文章的作者来说,则是绝对的坏事。想要对C语言体系中的开放资源做一个介绍,哪怕只是一次白描,也决不是一个人、一本书所能容纳的,更远远不是杂志中的一篇文章所能及的。因此在本文中,对于C语言开放资源的介绍是以一种蜻蜓点水的姿态进行的。
相比之下,C++语言在开源世界中的分量,与C语言相比就相去甚远了。作为对照,C++语言在工业界的实际地位,如果不是比C更重要的话,至少也是与C在同一个层次上。考虑到这一点,在开源领域中两兄弟的这种差距就令人感到非常震惊。如果说在2000年以前,由于C++在工业界的统治地位,这种差距对C++的影响还不大的话,今天,C++在开源领域里薄弱的基础就非常要命了。现在在开发者社群中,“C语言万寿无疆,C++无寿无疆”的说法得到不少人的支持,其根本原因之一就在于C++在开源运动中的地位远逊于C。究其原因,归根到底是因为编写高质量、可复用而又拳拳服膺的C++程序库实在是一件太困难的事情。一方面,大量的C++开源项目质量不佳,而且经常以一种粗暴的方式要求使用者改变自己程序的风格,另一方面,一旦有人完成了一个可用的C++项目或者程序库,他必须具有极其彪悍的意志才能够咬着牙把这样的项目奉献给开源社群——不仅因为失去了可能的金钱上的回报,更因为可能要面对着暴风雨般的批评和鄙视。总之,诸多的原因使得开源文化未能在C++中深深扎根。
然而,毕竟C++是一种称霸一时的语言,C++社群的规模、强悍和创造力,仍然是很多其它新兴语言社群难以相比的。特别是在标准C++制定之后,C++编程风格有了明确的指导思路,开源项目也就大大繁荣起来。虽然时间还不长,但是已经有一些令人欣慰的成果。这些成果也就构成了写作本文的基本动机和素材。
就重要性而言,开源程序库和工具集对于C++甚至比对C还要重要得多。因为实践证明,没有良好的基础设施支持,C++开发成功的可能性异乎寻常的低。其根本原因是,用C++写优秀的程序库非常非常难,而一旦有了这样的程序库,在其基础上写应用程序就相当容易了。同时,C++的特点又要求基础设施的源代码必须开放,因此,C++程序库对于开发者来说意义非常重大。
我们可以更进一步探究开源C++程序库对于C++开发的重要意义。用C++编写可复用程序库时所需要的思想方法和技术风格,与用C++编写应用程序时所需要的思想方法和技术风格之间存在相当大的差异和差距。前者所需要的高超技术、丰富经验和良好的权衡能力,是很少有人能具备的。在所有程序设计语言中,你恐怕找不出第二种语言像C++那样,对于程序库作者的要求如此之高,以至于远远超过了一般“熟练”C++开发者的平均水平。在Lisp中,语言、库和程序根本就是一回事,每一个程序员写的代码都可以看成是语言本身的扩充。在Java、C、Perl、Python、Ruby中,一个优秀的应用程序开发者在积累一定经验之后,不难写出高质量的可复用代码。而在C++中,这种事情是非常罕见的,即使是天资卓越、经验丰富的大师级人物,也需要花费多年的打磨,历经几次反复,才能够最终推出受到一致认可的可复用程序库。此道之难,难于上青天,以至于Andrei Alexandrescu感叹道,十几岁的少年天才满目皆是,满鬓斑白的优秀程序库设计者凤毛麟角。而在另一个地方,一本C++可复用技术图书的作者总结道,所谓可复用的C++程序库,不可能是设计出来的,只可能是复用出来的。然而,一旦这样的程序库构造出来并且为人们熟悉,那么就会大大地简化应用程序的开发。这也就是为什么在2000年后,Bjarne Stroustrup无数次地呼吁社群专注程序库的开发。他很清楚,只有程序库能够救C++,只有程序库能够发展C++。
现在我们知道,用来写C++程序库所需要的技术,与用来写C++应用程序所需要的技术存在很大的差别。这已经比较糟糕了。更糟糕的是,一般的C++开发者根本分不清这中间的差别,他们在开发中往往既不是一个称职的程序库开发者,也不是一个单纯的应用开发者。他们一边想着完成手头的工作,一边琢磨如何能够写出高质量的基础库和框架,为万世开太平。如果说C语言是一把轻快的小匕首,遇谁都是进身猛刺,血溅一尺,那么这种C++的使用方式无异于左手打铁铸兵,右手挥剑刺秦,这种精神分裂的状态直接将很多项目变成了既超期超支又质量低劣的垃圾。
认识到这样的事实之后,C++程序员应当以更理性的态度来看待自己的工作。大部分情况下,你所需要做的是寻找一些可以互相合作的、稳定可靠的开源程序库,然后在其基础之上,面向目标,使用尽可能简朴的技术,专心专意地进行应用开发,把那些复杂精妙的语言技巧和“可复用”之类的想法扔到Java国去。唯其如此,你才可能更高效地开发出好的应用软件,而且会逐渐积累和重构出真正可复用的软件。
评论
littlestone 发表于2006-04-27 01:27:00 IP: 222.212.69.*| 首发啊,赞一下先! 用过了N种语言以后,还是感觉C/C++最贴心. |
want 发表于2006-04-27 05:15:00 IP: 131.252.223.*| 过分卖弄你的文字只会损坏你的文章 |
周星星 发表于2006-04-27 10:39:00 IP: 218.94.94.*| 看到一半,我猜只有“孟岩”和“刘未鹏”有这个水平写出如此深刻而客观中立的文章,而从口气与风格上极像孟岩。 一看作者,果然猜对了。 |
Cythier 发表于2006-04-27 08:59:00 IP: 222.94.6.*| 赞同! |
sunxiunan 发表于2006-04-27 11:09:00 IP: 208.22.104.*| 不知道有没有数据上的比较,比如说c++多少开源项目,c多少开源项目。这样空口白说,没有说服力。 说的这些观点,哪些是有“典”的,哪些是自己的,应该说清楚一点。 立论不坚实,煽动性感性的词汇太多,文章总体感觉一般。 |
myan 发表于2006-04-27 11:33:00 IP: 219.236.60.*| to sunxiunan: 得出数据很容易,到sourceforge上搜一下就行了,得出观点就难了,因为你从搜到的数据中根本看不出问题。跟在数据后头永远都是迟钝的。你要立论坚实,不过坚实的立论基本上都是马后炮。 文章是我写的,观点当然是我自己的。 风格问题,尊重你的个人的感觉。写东西表达观点而已,风格只是装饰,不求讨天下人喜欢。 |
onlyxuyang 发表于2006-04-27 12:32:00 IP: 221.232.153.*| 觉得C++永远不可能灭亡的 打个比方....历史的道标 就算有一天退出了前台,也会在背后引导着人们的前进 我一直认为,就其语言本身来说,C++所蕴涵的东西是没有任何语言可以匹极的. |
kyan 发表于2006-04-27 12:48:00 IP: 222.66.13.*| 废话太多, |
Hdx127 发表于2006-04-27 12:55:00 IP: 218.202.219.*| 文明越发达,分工协作越明显。这种现象对C++这种混合性的语言同样适合。对开源程序库和对应用程序的开发必须分开,才能拯救C++! |
dhatqd 发表于2006-04-27 13:08:00 IP: 222.174.132.*| 发人深思,感觉C++程序库的作者时刻处于两难境地,许多设计决策一旦作出就相当于放弃了C++语言的一部分灵活性,要做成专用的程序库还好说,想做成象C++语言本身那么通用的就难了。 |
dfdd 发表于2006-04-27 14:20:00 IP: 200.118.2.*| 不知道有没有数据上的比较,比如说c++多少开源项目,c多少开源项目。这样空口白说,没有说服力。 -- 很明显,这是针对“C++语言在开源世界中的分量,与C语言相比就相去甚远了。”。 -- myan说“得出数据很容易,。。。不过坚实的立论基本上都是马后炮。”没有说到点子上。 -- 和sunxiunan感觉一样,myan这篇文章空口白说的太多。再比如:“今天C语言体系内所拥有。。。其项背的。”, “C++语言在工业界。。。C在同一个层次上。”,“大量的C++开源项目质量不佳”,“他很清楚,只有程序库能够救C++,只有程序库能够发展C++。”这些不见得都不对,但在这里都基本上都是没有根据的断言。 -- 另外,感觉myan对C++库的断言过于绝对。不知道Bjarne Stroustrup看到你这样臆断(他很清楚,只有程序库能够救C++,只有程序库能够发展C++),会怎么想。事实上,Bjarne从未觉得C++在将死的边缘上(参看他的主页的FAQs)。 |
ifree 发表于2006-04-27 13:17:00 IP: 222.51.223.*| 整篇文章除了说了一句:只有程序库才能救C++外,通篇都是卖弄文字的废话。 |
dawndu 发表于2006-04-27 17:11:00 IP: 58.212.74.*| 文字不错,废话太多 c++写程序库那个模板不是凡人能掌握好得 |
oreofish 发表于2006-04-27 16:10:00 IP: 141.202.248.*| 乍一看有理,细一想,说明不了什么问题。 C++语言在开源世界中的分量,与C语言相比就相去甚远了 ----即使这个说法正确,也是因为很多系统级开发需要用c开发,只与语言的适用领域有关 在Lisp中,语言、库和程序根本就是一回事 ----c++的重载/封装也达到了同样的目的。 用来写C++程序库所需要的技术,与用来写C++应用程序所需要的技术存在很大的差别 ----这一点是语言无关的。 Java走到今天,很大程度上是因为其无法避免反向工程。 |
longaway 发表于2006-04-28 18:32:00 IP: 221.216.100.*| 好早啊。 |
nbw 发表于2006-04-29 09:49:00 IP: 219.133.51.*| 废话连篇 |
sevencat 发表于2006-04-29 08:12:00 IP: 222.68.42.*| 就是这样,C++把模板丢掉可能还会更好些。 过分玩弄语言技术和固步自封不会带来什么好结果的。 |
小虾 发表于2006-04-29 10:36:00 IP: 219.149.236.*| 孟兄的文章似乎沾染了不少媒体的浮夸之风,少了科研所具有的事实与严谨。 |
sevencat 发表于2006-04-29 08:14:00 IP: 222.68.42.*| 在Lisp中,语言、库和程序根本就是一回事 ----c++的重载/封装也达到了同样的目的。 c++里面写一个大家都可以随便重用的库太难啦,难到不太现实了。 用来写C++程序库所需要的技术,与用来写C++应用程序所需要的技术存在很大的差别 ----这一点是语言无关的。 还是有关吧。用JAVA写跟用C++写差别很大的。 C++的语法已经更复杂了,我们需要的是更简单。 |
Rural 发表于2006-04-29 10:37:00 IP: 218.104.96.*| 我现在还想不出来任何评论。。。 以后再继续关注。 |
饕餮西门 发表于2006-04-29 12:43:00 IP: 203.156.208.*| 骨骼特异 |
ilovevc 发表于2006-04-29 13:37:00 IP: 152.104.165.*| myan总是过于多虑,以前遇到个C++/CLI好像逮个宝贝似的,说什么“凤凰XX”的,好像就是C++又能死去活来的意思,现在看到C++/CLI实在是不符合C++胃口,又觉得只有库才能拯救,不过不知道你列出的名单。 C++还没有那么惨吧!别人不知道,我现在在嵌入式上用它爽得很。不过使用的库还确实都是C的。 |
jsblcg 发表于2006-04-29 13:18:00 IP: 219.148.158.*| 各有各的好处: Java简洁、移植性强,但没有C++中的操作符重载,没有模板,代码编写有时候有些啰嗦难看,无法控制的垃圾回收使得Java在对内存要求较高的高性系统中难以应用。解释执行的效率在一些系统中是无法接受的,虽然听说可以编译成本地代码,但它的最初设计就是虚拟的,一些特性(例如运行时的类型信息)恐怕很难有高效的代码。 C几乎无所不能,语法也很简洁,但没有重载,多态等特性,编写应用程序有些复杂。 C++也是几乎无所不能,但有OO特性,比C适合编写应用系统,但复杂晦涩的语法以(例如模板)及一些实现上的细节问题非常让人头痛 ,对程序员要求较高,尤其在大系统中。 不过,由于C++几乎能够完成任何任务,不用担心在实现系统过程中遇到与性能有关的困难。用Java实现就有这种担心。 |
jsblcg 发表于2006-04-29 13:25:00 IP: 219.148.158.*| 目前,似乎只有C++有STL这种算法级的库吧?Java中有一些,但那是通过虚拟函数和回调函数实现的,而且仅限于几个集合。C++可是面向所有算法的,几乎没有限制。当然,STL的语法和使用都有点晦涩。从长远看,这是代码复用的极致,即算法复用,套用一句Java名言,一次实现,处处使用。 当然,我是C/C++发烧友,对Java/C#的理解远不如C/C++,说得可能偏颇。 |
freebsd 发表于2006-04-29 13:30:00 IP: 218.106.82.*| 感觉到中国的评论风气有点可笑.词藻修饰,就是"废话连篇";抒己之见,就是"浮夸煽动".仿佛非要出言不逊方才显示自己的"高人一等". 当然,严谨是必要的.我觉得有一些"独断"的部分,譬如开始写Pascal,早期Pascal是有缺陷的,而且标准又出来的太晚.创造C写UNIX就是因为其他语言不适合,和开源没什么关系. 总的来说我喜欢这种文章!该写什么写什么,"我笔抒我心".从标题就能看出和那些炒作的文章不一样,没什么能吸引眼球的词.比那些违心的,写套话的,却又找不出漏洞的文章比,美得多了! |
copine 发表于2006-04-29 18:26:00 IP: 203.81.22.*| 这篇文章写得不错,读的时候我笑出来两次。 |
Shawn 发表于2006-04-29 23:59:00 IP: 221.10.24.*| 希望这种文章不要出现在<程序员>杂志上,这样不怎么对吧,Bjarne Stroustrup对于C++的发展还是非常乐观的,微软的C++/CLI绝对不能代表ISO C++. |
sunxiunan 发表于2006-04-29 15:08:00 IP: 208.22.104.*| 十年磨一剑,对于一篇blog来说当然不必如此。 不过,对于一些基本的数据还是应该有一个说明的,我做研究生论文的时候就受过老师的此类批评,比如是否借鉴了别人的观点,不可能都是全新的,整篇文章都是观点未免有些不通,怎么也是有前言、现状、观点、结论这样的一些大结构。 或许我说的有些刻薄,不过既然是一篇稿件,自然要求和blog文章应该有所不同,是要读者花钱的,自己写着爽和让读者有收获还是有区别的吧。 |
sunxiunan 发表于2006-04-29 15:19:00 IP: 208.22.104.*| 挑一挑刺,我认为应该有论据的地方, 1)如果说在2000年以前,由于C++在工业界的统治地位,这种差距对C++的影响还不大的话,今天,C++在开源领域里薄弱的基础就非常要命了。 sunxiunan:应该有具体数据对比,怎么就要命了? 2)大量的C++开源项目质量不佳,而且经常以一种粗暴的方式要求使用者改变自己程序的风格 sunxiunan:是否有相关的数据评估,这个不佳是从何而来? 3)因为实践证明,没有良好的基础设施支持,C++开发成功的可能性异乎寻常的低。 sunxiunan:这个是最应该有数据证明的地方。 4)在Java、C、Perl、Python、Ruby中,一个优秀的应用程序开发者在积累一定经验之后,不难写出高质量的可复用代码。而在C++中,这种事情是非常罕见的,即使是天资卓越、经验丰富的大师级人物,也需要花费多年的打磨,历经几次反复,才能够最终推出受到一致认可的可复用程序库。 sunxiunan:抱歉,这里我并不同意这种观点,说得太过煽情,缺少说服力,难道C++就是一种不同星球的编程语言?程序质量的好坏还是在于写程序的人吧?语言只是工具。 5)以至于Andrei Alexandrescu感叹道,十几岁的少年天才满目皆是,满鬓斑白的优秀程序库设计者凤毛麟角。而在另一个地方,一本C++可复用技术图书的作者总结道,所谓可复用的C++程序库,不可能是设计出来的,只可能是复用出来的。 sunxiunan:我真的想知道大师在哪篇文章里说的这个话。 6)这也就是为什么在2000年后,Bjarne Stroustrup无数次地呼吁社群专注程序库的开发。 sunxiunan:要是有大师说话的原文链接或者书籍页码就更爽了。 抱歉我这样苛刻,或许这些都没有必要,但是如果有这些说明的话,这篇文章会更有说服力,现在网络如此发达,作者搜索原文应该要方便很多。 |
onlyxuyang 发表于2006-04-30 12:12:00 IP: 221.232.153.*| 平均本来就不是一种好趋势 直到现在,C++仍旧是高效率和易用的代表 |
ilovevc 发表于2006-04-30 08:43:00 IP: 152.104.165.*| C++的关键问题是离平均水平的程序员越来越远。 |
lovecreatesbeauty 发表于2006-04-30 17:57:00 IP: 210.21.221.*| > 如果Pascal也能借助一个像UNIX那样的开放的幽灵在欧美大学校园里徘徊,那么我们今天很可能要把begin和end直接映射到键盘上。 see: `...Pascal, at least in its standard form, is just plain not suitable for serious programming. ...' Why Pascal is Not My Favorite Programming Language Brian W. Kernighan, April 2, 1981 AT&T Bell Laboratories, Murray Hill, New Jersey 07974 http://www.lysator.liu.se/c/bwk-on-pascal.html |
shewo 发表于2006-05-01 20:07:00 IP: 218.18.78.*| C++不可能消亡,只会发展,这种发展不是扩展,而是简化,不过他体现的思想是不会消失的,因为他的思想本身来自于历史的积累 |
atu 发表于2006-05-01 22:45:00 IP: 210.82.103.*| 语言仅是工具而已,每一门语言都有他的优势和短处,其他语言能做到的,c++照样也能做到,个人觉的c++语言学习曲线较高,从而影响了它的普及。比如只会Java、C#的转到C++并不是那么轻松容易,而会c++的转到Java、C#则会容易的多。 |
corer 发表于2006-05-01 15:50:00 IP: 211.137.211.*| 这个个人喜好有关,毕竟c简单、实用、性能高 |
zz 发表于2006-05-02 21:10:00 IP: 222.91.246.*| ! |
haven 发表于2006-05-03 03:57:00 IP: 131.230.190.*| 为什么不写全了?给人感觉是既要做婊子,有要立排放.何必呢?那末在乎那点小钱? |
lihuiba 发表于2006-05-05 10:23:00 IP: 61.187.54.*| to :sunxiunan 发表于2006-04-29 3:19 PM IP: 208.22.104.* 2)大量的C++开源项目质量不佳,而且经常以一种粗暴的方式要求使用者改变自己程序的风格 sunxiunan:是否有相关的数据评估,这个不佳是从何而来? re: 我用了ACE,质量很高,不过确实非常“粗暴”,于是仍掉不用了。 3)因为实践证明,没有良好的基础设施支持,C++开发成功的可能性异乎寻常的低。 sunxiunan:这个是最应该有数据证明的地方。 re:深有感触。我编程序已经有十多年时间了,对C++的掌握也还算过关,但是做起实际项目仍然效率很低,痛骂C++没有大库支持,即便boost也还不够。 4)在Java、C、Perl、Python、Ruby中,一个优秀的应用程序开发者在积累一定经验之后,不难写出高质量的可复用代码。而在C++中,这种事情是非常罕见的,即使是天资卓越、经验丰富的大师级人物,也需要花费多年的打磨,历经几次反复,才能够最终推出受到一致认可的可复用程序库。 sunxiunan:抱歉,这里我并不同意这种观点,说得太过煽情,缺少说服力,难道C++就是一种不同星球的编程语言?程序质量的好坏还是在于写程序的人吧?语言只是工具。 re:推荐你阅读一下boost源代码,看看能不能看懂,这样你就知道一个高质量的c++库需要作者具有什么样的c++功力。 5)以至于Andrei Alexandrescu感叹道,十几岁的少年天才满目皆是,满鬓斑白的优秀程序库设计者凤毛麟角。而在另一个地方,一本C++可复用技术图书的作者总结道,所谓可复用的C++程序库,不可能是设计出来的,只可能是复用出来的。 sunxiunan:我真的想知道大师在哪篇文章里说的这个话。 re:这个并不重要,观点是绝对正确的。 6)这也就是为什么在2000年后,Bjarne Stroustrup无数次地呼吁社群专注程序库的开发。 sunxiunan:要是有大师说话的原文链接或者书籍页码就更爽了。 re:这个also并不重要,观点是绝对正确的。 抱歉我这样苛刻,或许这些都没有必要,但是如果有这些说明的话,这篇文章会更有说服力,现在网络如此发达,作者搜索原文应该要方便很多。 re:这个不是科学论文,也不求进入sci,更何况,如果言必称孔孟,如何创新发展超越? 在我看来,这篇文章立论非常到位,言语通顺流畅易懂,是难得的好文章。如果有人苛求什么,那么看看《时间简史》,里面好像只出现了两个公式,几乎没什么引用,但仍然风靡全球,呵呵。 |
absurd 发表于2006-05-06 17:25:00 IP: 211.161.63.*| 孟老师的文章真是妙笔生花,每篇文章我都会仔细读几遍。惭愧,恐怕我再努力五年也写不出这样好的文字。 |
Kingtao 发表于2006-05-07 09:43:00 IP: 218.83.112.*| 不但要开发库没, C++ 0x也要尽快出来. 这篇文章屁话的确挺多, 不过值得一看, 休闲还是不错得 |
if.q 发表于2006-05-07 16:29:00 IP: 202.115.130.*| 所谓可复用的C++程序库,不可能是设计出来的,只可能是复用出来的。很有道理哈 |
anonymous 发表于2006-05-07 23:15:00 IP: 61.147.147.*| 这是个价值观问题,大多学C/C++的仿佛都有种窥视癖,用一个东西仿佛非得先剥皮抽筋弄个究竟才行,这固然是好习惯,但该纯用的时候还是要纯用,STL/BOOST甚至Loki作为库,其user interface设计得不可谓不好,文档也算齐全,谁说不可以直接用来着,问题是很多人把“阅读其代码可以增进功力”当成了“我要接触它就得先读其代码”了。 比如很少听说做java的去通过阅读库代码的方式学习库的,因为java社群(似乎)没这么个“潜心态”。 根据我的经验,boost库里面的所有库都有很好的使用接口,不需要很深的C++知识完全就可以使用了。 当然,一部分人去阅读代码有可能是因为另一个原因,即使用的时候出纰漏了。实际上,这种情况下很多时候也完全不必去走阅读源代码这条路的,我相信绝大多数时候文档里面都有说明,只是很多人并没有耐性去看文档,托大地觉得那只是个多余的描述而已。 另外还要说明,boost库里面的绝大多数库甚至loki并无过度设计,由难以读懂推出过度设计,这个逻辑似乎没有逻辑。boost库难以读懂一方面是由于里面为了泛化、节省代码量等库设计所必须考虑的因素,从而使用的GP技术和宏比较多。另一个原因,恐怕是大多数人没有足够的耐心和钻劲罢了,叫这类人去读java库的源代码他们恐怕照样会说读不懂。我的经验是其实读懂boost代码只要一些最基本的模板知识和技巧,更多的是要耐心和热情。学习技术也是。 最后,实际上,C++的GP是库设计的有力武器,并非“可有可无”,含了GP技术构建出来的库,其适应性,泛用性,效率,甚至美观精致上都不是其他语言的库可以媲美的。很多人怀疑boost里面GP用得过火了,我怀疑他们只是不够了解boost才那么说,boost最大的缺点就是还不够丰富。 |
sevencat 发表于2006-05-07 21:52:00 IP: 222.68.70.*| boost和loki我已经决定要放弃了,在需要有些功能的时候,我宁可去选用一些C库。ACE还决定用,因为我起码能看得懂。 模板让C++好像走向一条不归路。N多的项目不用C++,不用模板,一样非常成功。(而且效率也不低),用了C++后有很多东东反而感觉有些过度设计 |
sevencat 发表于2006-05-07 21:54:00 IP: 222.68.70.*| 大家可以说我笨,连BOOST代码都看不懂,也许我只是不想在这些东东上浪费时间。 |
sevencat 发表于2006-05-08 06:15:00 IP: 61.173.162.*| 不是窥视癖啊,而是有时候你要是不知道他内部怎么工作的,有时候会死的,就像你是要使用ace而不去看原代码,多半会碰到这样那样的问题。java,c#的设计容错性和使用性比C++是好多了。所以可能根本不用考虑这样的问题。(其实java,C#也有人看他们的实现的) boost的代码其实我也看过一些。我不是很懂为什么有时候比较简单的一些东东为了考虑那个现在还不存在需求而设计出来的东东有啥用,举例如tokensizer,其实只要写到char,wchar就够了,一定要用模板吗?用函数指针不是更容易懂吗?我并不是因为难以读懂而认为他是过度设计的。 你要是认为读懂boost只需要一些基的模板知识就行的话,我认为我比较笨了。当然你也提到了耐心和钻劲,但是读的时候大部分时间放在一些纯语言上面,我还不如去关注一些实用的技术呢。java库原码mono库原码和2K原码,LINUX原码我都瞅过,但目前我认为我读过的最难读的原码就是boost的。 |
onlyxuyang 发表于2006-05-08 07:48:00 IP: 221.232.153.*| 楼上这位真的很可笑,没事情把 java库原码mono库原码和2K原码 拿出来说话,只能更进一步说明,你不行.不行到要拿自己看过的东西来掩盖你看不懂的东西. |
sevencat 发表于2006-05-08 08:34:00 IP: 58.246.57.*| 我只是比较一下这些代码的易读程度,你真的以为我看不懂boost代码?我只是不想再在这方面浪费太多的时间,我曾经花了不少的时间来看boost代码,没准比你看过的boost代码还要多。说老实话,我觉得在单纯C++方面,我也许并不比你差,我就是有这个自信。 |
foxdesign 发表于2006-05-08 09:22:00 IP: 221.5.148.*| 我也是一个C++的追随者,但目前对C++涉足较浅。 大家说C++可复用的程度比较困难,这是我所担心的。 |
anonymous 发表于2006-05-08 14:40:00 IP: 218.2.150.*| to sevencat: 毫无疑问,跟mono、2K、LINUX乃至.NET Rotor的源代码相比,最难读懂的就是boost代码。这个你是对的,甚至不夸张的说,boost的源代码不比任何库的源代码更易读(除了用像Perl这种可以readonly的语言写出来的库或者模糊C代码大赛作品)。 然而,正如我前面提到的,这个“难度”的原因,一方面是大多数人没有耐心和钻劲,另一方面,前面没有提到,恐怕就是模板在实际编程生活中被运用极少,所以大多数人看到一大摞的尖括号和"::"就已经先乱了阵脚,丧失信心了。所谓熟能生巧,可想而知,在国内现在的GP技术应用现状下,真正对template技术技巧熟悉的人有多少,这就直接导致了对大量运用GP技术的boost库的畏惧感,后者进而导致了boost的应用不广问题。就我的感觉,只要下点功夫仔细分析其中某一个GP技术运用得比较典型的库(如function、tuple等),熟悉了GP技术运用的“套路”和“模式”,熟悉了GP代码的逻辑和形式,对GP代码形成了一种审美感,后面再阅读就是坦途了,进而如果这时再回过头去看看STL代码,就会觉得实在很简单。 说到蕴涵的技术,GP技术的最大用武之地就是在库的构建上,特别地说,我个人觉得是在user interface的构建上。如果把一个基于GP技术构建的子库看作一栋大厦的话,GP技术在其构建中起到的作用就好比是骨架结构、门面装饰。不仅影响到整体的美感,还有易用性,适应性等。而适应性(adaptivity)我认为是GP给库带来的最重要能力之一,使用GP技术构建的库,其自身结构甚至都能够随着其被使用的环境上下文进行自发调整,这其实也就是Active Library的思想精髓,这种能力是借助于template的元编程能力实现的,某种意义上这是C++所独有的能力。扯远了,其实我要说的是,GP技术从本质上也是一门技术,跟mono、2K、Linux源代码中体现出来的操作系统构建技术,如内存管理、虚拟机实现、GC等技术相比,并无本质上的逊色与否,两者所处的领域不同,你完全可以因工作原因而更关注后者,不过我很怀疑后面这些技术在国内实际工作中的应用,其实大家阅读源代码大多是一出于爱好和兴趣,二出于技术储备罢了(说不定还有三:培养自己的代码审美能力,进而自己能够写出优秀的代码),当真运用到实战中的技术似乎少之又少。还是一些一般性的编码技术比较有用武之地,呵呵。 我个人还是建议大家多接触接触boost,可以从使用开始,你或许会发现自己平时经常想要用到的东西在里面都有现成的实现,毕竟,STL的天地太小了。熟悉了之后或许可以窥视一下其实现,定会获益匪浅。 |
sevencat 发表于2006-05-08 14:54:00 IP: 58.246.57.*| to:anonymous 发表于2006-05-08 2:40 PM IP: 218.2.150.* 从纯技术的角度上来说,这样说是没错,但是从项目和工程的角度上来说,是要尽量使用简单的东东,维护更容易的东东才行。而且同样是库,java,C#的接口是那么的易用和易懂, 举个很简单的例子,假如我有一个项目,里面充斥着模板,元编程,这样的工程在中国现在的维护难度大家可想而知。哪怕是自己可能都会有些地方搞不清楚。出于这方面的考虑,我宁可去选择C的库。 我经常发现自己所要的东东在里面找不到,或者正如上面有人所说,boost其实比ace的风格更加强暴。我不知道大家有没有仔细看过里面的一些实现,有时候为了GP写出了一些很丑陋的代码。 |
lovecreatesbeauty 发表于2006-05-08 16:00:00 IP: 210.21.221.*| > 在Java、C、Perl、Python、Ruby中,一个优秀的应用程序开发者在积累一定经验之后,不难写出高质量的可复用代码。 一个脚本语言根本不能与C、C++放在一块儿。 |
lihuiba 发表于2006-05-08 16:26:00 IP: 61.187.54.*| to 7cat: 个人实际体会:ACE是一个程序框架,也就是个程序半成品,所以程序员需要适应ACe的风格才能跟这个框架沟通;而boost只是个普通的库,它对程序风格的侵入性小得多,更何况boost风格与STL一脉相承,融合的很好,所以“boost其实比ace的风格更加强暴”是不对的。 ACE也有一些丑陋的设计(可能是折中的需要),这里不具体讨论了,但需要说明的是,ACE的文档太少,很多时候需要直接看源代码,或者源代码的注释才能确定语义。我已经放弃ace,转用boost::asio了。 使用boost、stl的API并不意味着自己的程序会充斥模板、元编程,恰恰相反,这些API设计良好的库使得使用学习曲线比ACE平缓,更容易上手。 |
anonymous 发表于2006-05-08 18:26:00 IP: 218.2.150.*| lihuiba说得很好,“使用boost、stl的API并不意味着自己的程序会充斥模板、元编程,恰恰相反,这些API设计良好的库使得使用学习曲线比ACE平缓,更容易上手。 ” 使用一个GP库决不代表代码中充斥着GP代码。另外,java,c#库的接口“那么易用和易懂”?我的感觉是,java实在是一门糟糕的库构建语言,其接口is anything but elegant。C#倒还凑活,为什么C#和Java不约而同地加入Generics?C#甚至闪电般地在3.0版本中加入了一堆suck up的特性,lambda/var/... 另外,对于一个framework来说,自然是“强暴”的,自然需要使用者适应它的风格,这种情况并非仅存在于C++的framework之中,任何语言构建的framework不都是如此? "经常发现自己所要的东东在里面找不到"只表明boost现在还不够丰富,并不能推出GP技术缺陷这个结论。 |
onlyxuyang 发表于2006-05-08 19:32:00 IP: 221.232.153.*| ACE绝对是非常好的一个框架,学习曲线陡和资料匮乏那也是没办法的事情.因为ACE的复杂而放弃ACE的人我只能说,你们不适合做高质量的东西. C++是永恒不灭的,没有什么语言可以代替C++的地位. |
ahao 发表于2006-05-10 17:40:00 IP: 221.137.221.*| 我相信c++0x出来后模板代码会比较容易读,我用c++也超过10年了,boost里的有些库我是必用的,比如smart_ptr,bind,function,FOR_EACH,regex,signal,thread,variant,如果不用,代码才会丑陋和臃肿,还有些非常好的库,我也在尝试着用,比如filesystem(下个版本支持unicode了),serialization,iostreams,xpressive,graph,spirit,iterators, minmax,mpl,propert_tree,python,wave等,虽然我至今还没看懂过一个boost的库,但这丝毫不影响我的使用,大多数的库的文档写得都很清楚了,我甚至在商业项目里用boost还没有发布的库,比如StateChart状态机和asio异步io,太好用了,没有这些库,我都不知道怎么写才能最高效,最优雅了. |
ahao 发表于2006-05-10 17:49:00 IP: 221.137.221.*| 补充一下,boost库里很多宏只是为了减少代码量的,还有因为要支持很多平台和不标准的编译器,做了很多workaroud,这些给阅读带来不少的难度,而且需要读的人对c++了解很深才行,但我认为代码本身不是很难 |
anonymous 发表于2006-05-10 19:10:00 IP: 218.2.150.*| to ahao: "虽然我至今还没看懂过一个boost的库,但这丝毫不影响我的使用"、"但我认为代码本身不是很难"。 没错^_^ 需要的就是你这样的具有实际经验的人来说话:) |
myan 发表于2006-05-11 21:07:00 IP: 219.236.49.*| 正如上面几位所说,其实C++的template代码看上去复杂,其实也就那么几板斧,打好基础之后,熟悉一些常用的技巧也就完全能过关。Boost的问题不是其代码“不可读”,而是如下这些: 1. 可交流性。高级的C++ template语法仍然很少为人所了解,在可预见的未来也看不到C++ template用法“大众化”的可能性。所以大量使用技巧性很高的template语法,给可交流性带来影响。 2. 实现上的缺陷。Boost还不够成熟,特别是各平台C++编译器在不少细微之处还存在大量的问题,这都会使boost的不少应用触礁。例如在嵌入式平台上,Boost的应用空间很有限。 3. 带来过长的编译时间,损害开发效率。 4. 发展方向上的问题:总的发展方向是将C++语言作为系统中核心部件的开发工具,而不是用C++开发整个系统。也就是说,C++今后将以与其它语言(尤其是动态语言)合作为主。而Boost中的很多东西(比如regex,比如一些functional的工具),在这些新的动态语言,比如Javascript, Python, Ruby, Lua中实现的优雅自如,因此就很少有非要使用C++ template来解决问题的理由了。 5. 时机的问题:很多大的C++项目是前些年开发的,普遍已经选择了某种C++技术框架,比如MFC,比如ACE,比如Qt,而这些框架也越做越全面,比如Qt,基本上也算是应有尽有了,这就使得用户更愿意依赖类似这样的成熟C++框架。而这些成功的应用经验也吸引新的项目继续按照这样稳妥地路线开发,所以总的来说给boost留下的应用空间不大。不充分的应用反过来会使得boost难以迅速成熟。 总之,我个人整体上不看好boost,但是对于其中相当多的组件还是非常欣赏的。可以这么说,如果boost早5年出现,会对C++的发展产生重大影响。 相对来说,我更关注C++ 0x标准。因为标准中容纳的新内容会得到各方普遍的高质量的支持。 |
sevencat 发表于2006-05-12 06:59:00 IP: 222.68.71.*| ACE绝对是非常好的一个框架,学习曲线陡和资料匮乏那也是没办法的事情.因为ACE的复杂而放弃ACE的人我只能说,你们不适合做高质量的东西. C++是永恒不灭的,没有什么语言可以代替C++的地位. //========================= 没必要扣帽子和喊口号吧。 因为复杂性而放弃是正常的。也没有什么永生不灭的东东。ace也不是很全,kqueue的封装还没有呢。 其实C++的template代码看上去复杂,其实也就那么几板斧,打好基础之后,熟悉一些常用的技巧也就完全能过关。 //=================== 对这句话我持保留态度。不是那么几板斧了,带来了N多的复杂性,代码更加绕了。 "虽然我至今还没看懂过一个boost的库,但这丝毫不影响我的使用"、"但我认为代码本身不是很难"。 //==================== 你运气很好。 |
onlyxuyang 发表于2006-05-12 12:13:00 IP: 221.232.153.*| 忽然发现这种讨论很没有意义,以后不发表评论了 让事实证明一切吧 |
lihuiba 发表于2006-05-12 09:39:00 IP: 61.187.54.*| to myan: 1. 可交流性。高级的C++ template语法仍然很少为人所了解,在可预见的未来也看不到C++ template用法“大众化”的可能性。所以大量使用技巧性很高的template语法,给可交流性带来影响。 //======================== 一个好的库应该具有精确定义的简洁的接口,这样才能更好的隐藏细节,也就不需要使用者去阅读源代码了。 2. 实现上的缺陷。Boost还不够成熟,特别是各平台C++编译器在不少细微之处还存在大量的问题,这都会使boost的不少应用触礁。例如在嵌入式平台上,Boost的应用空间很有限。 //======================== 在各种主流编译器上面应该没大问题吧? 嵌入平台不是主要用C吗? 3. 带来过长的编译时间,损害开发效率。 //======================== 我见过一些c程序,build也要十几分钟,甚至更多,当然模板用多了这个问题更严重,不过要是c++的include语义能够变成import语义应该会好许多。 4. 发展方向上的问题:总的发展方向是将C++语言作为系统中核心部件的开发工具,而不是用C++开发整个系统。也就是说,C++今后将以与其它语言(尤其是动态语言)合作为主。而Boost中的很多东西(比如regex,比如一些functional的工具),在这些新的动态语言,比如Javascript, Python, Ruby, Lua中实现的优雅自如,因此就很少有非要使用C++ template来解决问题的理由了。 //======================== 在这种系统中,c++主要用来完成2种代码,一种是上层脚本没法实现的功能,另一种是脚本速度不够的功能。在这种c++代码中,使用boost就很正常了。更何况,boost::python不就是用来跟python通信的吗?好像boost还有计划做lua的binding,然后会做一个通用的脚本binding的框架。 5. 时机的问题:很多大的C++项目是前些年开发的,普遍已经选择了某种C++技术框架,比如MFC,比如ACE,比如Qt,而这些框架也越做越全面,比如Qt,基本上也算是应有尽有了,这就使得用户更愿意依赖类似这样的成熟C++框架。而这些成功的应用经验也吸引新的项目继续按照这样稳妥地路线开发,所以总的来说给boost留下的应用空间不大。不充分的应用反过来会使得boost难以迅速成熟。 //======================== mfc差不多被ms放弃了,其后的windows form也不是主要发展趋势了。ace本来使用面就不广,不提也罢。Qt我不了解,不过好像wxwindows(wxwigets)名气更大些。 我觉得boost难以迅速普及的原因不是那些,而在于不够实用。boost功能主要有两种,一种是基础性的,其他语言内置了的功能,比如any、function、bind、iterator、range、mpl等;一个是理论、算法相关的东西,比如uBLAS、graph、random、之类。而实际工程上常用的东西反而不足,比如ui就没有,网络也是3月底才刚刚加入的(asio),缺乏平台相关的东西(比如com支持)。 总之,我个人整体上不看好boost,但 |
dawndu 发表于2006-05-13 13:00:00 IP: 58.212.74.*| sevencat的很多观点,我很赞同,我相信做过项目的人都应该有这样的看法,很多模板库的设计确实很优美,我觉得更多是学术的价值,在工程中使用要冒很大的风险。boost这些库,你不看懂它,你敢在一个工程中用?就算你看得懂,你能担保你开发组有多数人能看懂?这样代码的维护性就很差了。上面有个兄弟说,用boost库从来没出过问题,我确实只能说你运气很好。MFC相对来说简单很多了,可是使用时还是有很多问题的,我想大多数人都有跟到MFC源码的经历吧?研究研究是好的,用就是另外的事了。 |
ahao 发表于2006-05-12 18:04:00 IP: 221.137.221.*| 我就不明白乐,一面抱怨c++没库,一面有这么好的库又不肯用,windows api 没源码不也用得欢吗?更何况boost是有源码的,实在不行出问题乐,上新闻组问问不行吗?不过这个就随便你乐,我也不想多说啥乐. |
xgz 发表于2006-05-17 09:23:00 IP: 203.156.210.*| 写个帖子也要科学,严谨啊?累不累? 写出形象,写出具体才易于理解,不然,比喻的手法有什么用? 又不是写数学。。。 |
hyifeng 发表于2006-05-19 11:08:00 IP: 202.105.135.*| 基于template设计的高科技东西,许多都是违反直觉的, 不象单纯的面向对象库, 没有文档和示例的帮助几乎不能写出代码来。 而且泛型库是无可避免会带来编译时的问题, 当文档缺乏描述(不可能全部的细节都说到),就不得不了解代码。 我赞同7cat的说法。 如果是一心一意地搞c++,深入进去学习也未尝不可。 |
chendp 发表于2006-05-26 18:16:00 IP: 210.72.232.*| STL真是十分好用。好的库接口相当明白,有很好的抽象,复用性就很好。写应用和写库不同,应用利益在于眼前,但是一个公司开发产品,不能都作应用,三年五年,怎么在自己领域也需要一个成熟的类库。如果所有人都只想完成自己手头的工作,那么公司肯定发展的不好。 |
chendp 发表于2006-05-26 18:16:00 IP: 210.72.232.*| STL真是十分好用。好的库接口相当明白,有很好的抽象,复用性就很好。写应用和写库不同,应用利益在于眼前,但是一个公司开发产品,不能都作应用,三年五年,怎么在自己领域也需要一个成熟的类库。如果所有人都只想完成自己手头的工作,那么公司肯定发展的不好。 |
dup 发表于2006-06-01 18:49:00 IP: 210.78.34.*| 我觉得boost之所以代码的复杂度比较高,并不是因为使用模板导致的,而是boost想要在现实中生活,想要成为一个工业级别可用的库,必须适应各种各样不完善的不一致的编译器实现导致的,这确实让boost代码看起来非常的绕。 另一个不得不说的原因是boost相对关注的是比较低级的领域,其实现对于性能的关注比较强烈,所以有时候难免对于风格和可理解性造成障碍,但是我觉得boost这个倾向是对的,它就应该定位成库的库。 另外,我也同意boost对程序风格的侵入性比ace少。ace是一个应用框架,而boost只是一个类库而已,虽说其包含的部件很多,但是它本身并没有试图形成和约定一种应用框架。 |
myan 发表于2006-06-01 20:08:00 IP: 219.236.54.*| to dup: boost复杂当然有它的原因。boost要追求代码的最大程度的效率和可配置性,因此大量运用模板技术来实现compile time retrospection, 即所谓“template meta-programming”。何谓“meta"?meta就是information about information。boost的一个基本思想就是在编译期根据class中提供的information进行计算、配置,产生最优化的代码。 从理论上讲,没人能说boost有什么不对的。但是在实践中,boost就是推广不了。陡峭的学习曲线,别扭的代码风格,漫长的编译时间,都跟时代的要求格格不入。因 |
dup 发表于2006-06-05 09:08:00 IP: 210.78.34.*| template meta-programming! 呵呵,我觉得你说的比这个词在大多数人心目中表达的范围要广一些。大多数人的意见是:编译期的运算能力,你说的是traits或者别的手段的获得对于类型的内省能力以及使用这种能力进行特化或者偏特化(部分特化)以追求最适应于类型的操作。 这一点上C++的问题确实比较大,C++的一个基本倾向是把各种类型信息和检查都在编译期完成,运行时的支持和负荷很小。而C++98其实并没有什么特别强大的机制用来获得编译期间编译器所能给出的类型信息,所以,不光是代码风格的别扭,其实还有思维上的别扭,明明是垂手可得的信息,非得用很多技巧才能搞到手,郁闷啊。 不过,据说C+0x中已经给出了一个非常强大和统一的机制来获取这些信息了,那时候boost的内部应该就不会这么丑陋了。C+0x的concept也是编译期的范型所必需的东西,以前没有这个的痛苦也希望能够随着它的出现而解除:) |

