C++不是万能的

除了模式,上周日我和sunway还谈到了C++的问题——结果周二就看到Linus Torvalds就C++的话题跟人吵架,引发了国内C++圈里的大讨论——孟岩版云风版刘未鹏版。我也来扯一篇吧,不过层次肯定比这帮职业C++高手差多了。

云 风最近一次从C++回到C我是知道的,还曾经因为C是不是需要提供GC的问题跟他有过讨论。那天sunway跟我讨论的主要观点跟云风及Torvalds 差不多,其实他们也没有说C++就是绝对的一无是处,但是C++也绝非万能——我觉得这是在这次争吵中,C++铁杆支持者们所犯的最大的错误。

作为Git的核心开发者,Torvalds选择C当然有他自己的理由,Kakurin如果觉得不爽,大可以自己用C++写一个类似的东东来比拼一下嘛。

其实我并不是很认同C++中的所谓“mental包袱”的说法,是不是包袱关键还要看用的人。如孟岩所说的《用C设计,用C++编码》就是一种摆脱“mental包袱”的方法。但是必须承认的是:绝大部分人还是会被这所谓的“mental包袱“所影响。当你在程序中用上了STL, boost甚至loki的时候,难免会不由自主地越陷越深,抽象程度越来越高,最后不可避免地走向过度设计和过度抽象,背离最初的目标。但是C没有提供这 些可能性,所以C程序员只能很直接地奔目标而去,把所有的抽象都抛在脑后。

我觉得C++和C就如同武学中的不同门派。C++属于那种招式很 华丽,耍得好也有很大的杀伤力武功;而C则属于那种招式简单朴素,但是练到一定的功力,在有些时候会更加有效。如同打狗捧法与降龙十八掌。而对于内力深厚 的高人来说,通常会更喜欢后者,因为它更加简单直接,一击致命。

duyanning在孟岩那里的回复很 有代表性。表面上很对,没搞清楚std::string的实现就用,出了问题怪std::string不好的确是没有道理,但问题是对于一个团队来说,一 个leader实际上不可能给成员们划一条很清楚的道说在项目中哪里可以用std::string哪里不可以用,而让每个成员都去研究std:: string背后的实现也是没有必要的——与其如此还不如直接用C,清楚明白。

后来sunway和我在MSN上也谈到这个问题,STL、 boost、loki是好,但是并不总是好用的。在他的项目应用中,用STL存在着性能问题,所以他们是自己实现的一套模板库。因为有针对性的实现可以少 考虑很多通用方面的问题,而且这样有针对性的实现对于性能优化也很有帮助(我记得在ACE里也是因为性能的关系,有一套自己的模板库)。既然STL都 是可能被抛弃的,C++其它特性当然也有可能在某些情况下可以被抛弃,那种时候用C就是更好的选择。

如勒庞在《乌合之众》里所说的,当一群人聚在一起的时候,群体的水平只会比每个个体都低——因为只有在这样低的程度上,他们才能达成共识。这与木桶原理还不一样,木桶的盛水量是由最短的那根木板决定,而人的群体结果会比最低者还低。

以C ++为例,我与令狐有过一个简单的讨论。我认为在团队中使用C++的高级特性面临的主要问题就是:C++很强大,但是大部分人不具备完全理解和使用的能力 (令狐指出:不是大部分人,我觉得是绝大部分人,包括很多C++专家)。如果一个团队每个人都只熟悉其中的一部分,而且是各自不太相同的部分,那么这个团 队就很难正常运作。除非让大家都保持在一个较低的水平,只使用大家都熟悉的部分,那么这样与C相比,多出的部分就已经不是很多了,有时候确实会有用C更好 的情况。

其实在C++的feature问题上,sunway和我及令狐有一个差不多的共识,C++现在根本不是feature太少的问题, 而是feature太多的问题。对于那些将要被加入的如lambda之类的东西,我是持反对意见的。因为如果我真有这类的需求,我会换用更合适的语言来 做,比如python。

正如令狐对C++定位的评价(大意):

C++貌似无所不能——在低阶方面,可以做到与C一样低阶;而 在高阶方面,可以借助各种库等手段,在应用层面上把指针完全消灭,做成貌似JAVA那样。但是问题在于C++在低阶一端不如C(因为C简单而直接,编译效 率很高,而且目标代码也干净很多——仅指按C++方式编译时目标代码不够干净),在高阶一端更是不如JAVA(缺乏GC等高阶特性)。所以C++目前的定位比较尴尬。

sunway的观点则如C一般简单直接:

……希望C++能抛弃那些华而不实的东西走上正轨……什么都支持还不如只支持一种……

我基本赞同他们的看法,所以我也不认为C++应该继续增加feature,更不认为feature很多的C++一定会比简单的C更好。

补充:当然C同样也不是万能的,只是在有些情况下,相比C++而言,C的确会是更好的选择。总之我的观点还是——视实际情况选择语言,而不是试图用一个语言解决所有问题。