【引自孟岩的博客】Linus Torvalds曾经在十多年前尝试用C++(www.cppentry.com)来开发Linux内核,由于种种原因,很快失败了。自那时起,他就不时表达对C++(www.cppentry.com)的不满。刘江翻译的那篇《Linux之父炮轰C++(www.cppentry.com):糟糕程序员的垃圾语言》只是最近的一次而已。尽管言辞激烈,但其实话糙理不糙。
时至今日,在一般的场合下,C和C++(www.cppentry.com)语言的主要用途就是系统级软件的开发。具体地说,C/C++(www.cppentry.com)写平台、工具和基础库,支持高层的语言来完成应用逻辑。在《微软架构师谈编程(www.cppentry.com)语言发展》的文章里,Brian Beckman直截了当地说,C++(www.cppentry.com)语言主要是用来开发别的语言的。这话片面一点,如果改成 “C++(www.cppentry.com)语言主要是用来支持别的语言的”,那就大体没错了。
做系统软件开发的时候,重要的是理解系统的运作方式,那些漂亮的抽象手法和高级特性是次要的。
有一个有趣的现象,不少做系统软件的老手,在用过一段C++(www.cppentry.com)之后,又回到C。因为在这个层次上,C++(www.cppentry.com)对于C的优势就不突出了。那些高级的抽象结构往往是不必要的,反而是由于抽象层次的提高,使得开发者要弄清楚“下面实际发生的事情”变得不太容易了。所以很多老手实际上觉得用C语言控制力更强一些,更得心应手一些。真正的C语言高手,对于语言和编译器都很熟悉了,基本上在写C的时候就已经知道编译器优化以后产生汇编代码是个什么样子,甚至可以改变C代码来引导编译器产生最优化的机器码。而C++(www.cppentry.com)的机制很丰富,很多机制是为了满足高层应用和框架的需求而准备的,在这个层次上发挥不出来,反而把清晰性给牺牲掉了。很多时候,一个简单的语句,到底背后会发生什么,即使是老手也说不清。比如:
std::string s(“Linux Torvalds"); std::string scopy = s;
|
上面这段代码不过是创建两个内容相同的字符串副本,但是没有任何一个人能够在不了解更多信息的情况下清楚地描述背后所发生的事情,因为不同的STL对于string的实现方式不同,因此在copy assignment时表现也不同,有的可能是简单地复制字符串对象,有的可能具有ref-counting机制,需要创建对象、设定对象值、增加引用计 数,有的没有考虑线程安全性,有的考虑了线程安全性,还得加锁解锁,而且加解锁也还有很多做法。创建新的string对象时,有时还需要调用内存分配器,而这个东西的实现又五花八门,有的直接new char[],有的从内建的memory pool申请,memeory pool是不是线程安全的?对不起,这次可能又要涉及加解锁问题。memeory pool会不会已经满了?要不要依次调用new/malloc申请新的内存块?总之,后面的事情够多够复杂,没有相当功力,对平台了解不够深入,很难说出个子午卯酉来。
一个字符串复制尚且如此,别的高级特性就更不用说了。所以很多人宁可麻烦一点,也不愿意使用C++(www.cppentry.com),这还是可以理解的。
就我个人来说,我还是愿意用C++(www.cppentry.com)的,特别是在C里写一遍又一遍realloc的时候,就想起string::operator+=()的好处来了。大概是STL给我的印象太深了,写算法程序的时候,不用STL就觉得不爽,一个transform就可以搞定的事情,非要用for循环,这会让我感觉浑身不自在。所以一般情况下,拿到一个什么问题,我还是会用C++(www.cppentry.com)去解决的。对我来说,Torvalds的话其实是很中肯的,即使是用C++(www.cppentry.com),也要尽可能搞清楚其背后发生的事情,这样在写low level程序的时候才会有把握。如果是设计应用级别的程序,就尽可能不用C/C++(www.cppentry.com),把底层的事情都忘掉,专心专意做好应用层的设计才是正道。
【相关文章】
【责任编辑:
火凤凰 TEL:(010)68476606-8036】