为什么C++(来自C++之父的观点)
By Bjarne Stroustrup
http://www.research.att.com/~bs/
刘未鹏(pongba)
C++的罗浮宫(http://blog.csdn.net/pongba)
注:9月份的时候写了一篇“Why C++”(翻译版见这里)。后来我把文章发给Bjarne,问问他的意见。Bjarne友好的对文章作了详细的评点并发回给我,我问他能不能把他的评点版发到blog上,他说原先发给我的评点比较随意,答应给我单独写一篇友情评注,也就是下面这篇。
在后来的邮件交流中,我又问了Bjarne一些C++问题,并得知Bjarne的新书将会在夏季出版,在我们的交流中我曾问起他所说的正确的学习C++的方式到底是什么,他说他的新书将会是最好的答案!
此外Bjarne还答应接受一次访谈,这个我已经在上次一篇blog里面提到了,引用如下:
“最近和Bjarne Stroustrup的通信中,他答应接受一次访谈。
为了让访谈能够代表更多人的意见而不是我个人的感觉,在这里邀请大家提出自己最想问的问题。
你最想问什么?
BTW. 由于我会对问题进行筛选,然后再公布给大家投票。所以大家的问题最好是深思熟虑的,重要的,有理有据的:-)
问题后如果能附上问题的背景(即你在什么样的经历中发现这个问题很关键)那是最好不过!
问题可以留言在blog上,但更建议发到TopLanguage上,我专门开了一则帖子,这样大家可以互相讨论:-)”
以下是Bjarne的原文(抱歉,我没有时间全文翻译出来,如果哪位同学有兴趣译出来的话可以先跟我说一声——这是为了避免多人在互相不知道的情况下重复劳动。另外我会在翻译版上署上你的名字和链接(如果有的话)):
Dear “pongba”,
You sent me a long and thoughtful note about C++ and its use – or lack of use or misuse – in your environment. I answered with a set of disjointed comments on your note that unfortunately were not suitable for a wider audience, such as your blog. This is the slightly revised set of those notes – made a little bit more coherent, but still not of the quality of a proper paper – that you can post (incl. this little explanatory note):
C and C++
You worry that many people prefer to use C over C++ and that there may even be a move away from C++ towards C. You are being unnecessarily defensive. Don’t forget that for major applications, the move has been from C to C++ for a very long time. If people “frown and turn away,” they are displaying ignorance. Don’t be defensive: Challenge the unsupported myths! My applications page (http://www.research.att.com/~bs/applications.html) is a good place to start. If there really is a drift from C++ to C – which I have never seen in the US or Europe – then it speaks badly on the education of the “drifters”. Organizations caring about quality code have consistently drifted the other way.
People often say that C is simpler than C++. They consider that obvious (just look at the thickness of the C standard compared with the C++ standard or K&R2 compared to TC++PL3. The question is “simpler for what?” I don’t know of any program that can be simpler when written in C than in C++; I don’t think such a program is possible. C++ provides better notational support and better type checking for the things that C does well. Improved type checking is important and its importance increases with the size of the program and the demands of correctness: C simply leaves you in the lurch and doesn’t provide facilities to express even a simple concept as “buffer” directly and without overheads. Don’t fall into the trap of equating C++ with OOP or GP. Those are powerful techniques where appropriate. Just because you don’t need OOP or GP for a project doesn’t imply that C is better for that. My claim is that it is not.
C is nota simple language and programmers have no problems misusing it. Please explain the rules for conversion from unsigned short to int or try to teach a novice how to deal with pointers to pointers. Note the need for workarounds for just about any modern or large-program technique. How many dark corners are there in C? Examples: explicit memory management, standards conversion and promotions, multidimensional array addressing, pointers to pointers, and macros. In the absence of C++ features, you get to use them all directly. How many necessary modern programming techniques do you have to apply through workarounds in C?
Complexity will go somewhere: if not the language then the application code.
It is sometimes claimed that C is more efficient than C++. There is absolutely no evidence that C is more efficient than C for any reasonable definition of “efficient”. There are fundamental reasons that C cannot be more efficient than C++: They share a machine model and a set of basic facilities to use it. For lots of details related to C++ performance see the ISO C++ committee’s Technical Report on performance (link on my C++ page: http://www.research.att.com/~bs/C++.html).
But yes, the simplicity of C and its efficiency as compared to C++ are popular myths; in places they are so popular that people feel that no evidence is needed for their support. Unfortunately, such myths are not harmless; they damage the performance of individuals and organizations that buy into them. For a more detailed and precise statement of my opinion of C’s relationship to C++, see my papers on that topic: http://www.research.att.com/~bs/bs_faq.html#merge . See also my paper on learning C++: “Learning Standard C++ as a new language (link on my publications page).
It is really hard to think of an area where C is better than C++ today. It would have to involve lack of decent C++ compilers and/or tools (such as CNU C++ or Microsoft C++ 10 years ago – many people still express strong opinions on C++ based on experience with such compilers) or it has to involve a lot of existing code that happens to make C++ hard to use (e.g. header files with lots of C++ keywords used as identifiers).
C++ techniques
C++ != OOP. Trust the programmer to choose which language facilities are appropriate – even your colleagues. Using C out of fear that someone will use an inappropriate language feature is bizarre: our systems are extremely complex and depriving the programmer of even type checking out of fear of complexity is either misguided or disingenuous.
Yes, we could build a better string than std::string, but std::string is still better than *average* C string manipulation: gets(s) – enough said. Optimize only where needed; go for correctness and simplicity everywhere.
There is no reason why code expressed using abstractions should be less efficient than equivalent hand written code (in C or C++) using lower-level features (pointers, char arrays, etc.). The most performance-critical C++ code tends to use templates (and classes): e.g., high-performance computation and serious embedded systems. See the ISO C++ Standard Committee’s Technical Report on Performance and the JSF++ coding standard (available from my C++ page).
Obviously, a programmer can overuse abstraction mechanisms. Examples are designs that represent every idea as a class with lots of virtual functions in a single huge hierarchy and designs that represent every possible design decision as a template parameter. Good design is not just deferring all design decisions! Conversely, it is easy to underabstract. For example, try writing a set of mathematical functions for multi-dimensional arrays expressed directly as C/C++ multidimensional arrays. The result is something that passes array bounds as separate arguments – leading to bugs and run-time efficiencies.
C++0x
Some of the features coming in C++0x are exciting (e.g., concepts, uniform initialization, and the machine model), but we wont be able to rely on C++0x for another couple of years. C++0x shows where we are going, but if you want to defend C++, do it with minimal reference to C++0x. C++98 is a well-proven tool; C++0x will simply be better.
There are technical embarrassments in C++, such as the need for a space between > and > in “vector<list<int>>”. I was the one who named such technical problems “embarrassments” and listed several to encourage the standards committee to address them. No serious person considers any language in major real-world use perfect; they all have weaknesses that embarrass their expert users that should – if possible – be addressed.
Have a look at my papers written for HOPL (The ACM History of Programming Languages conference) to get a more nuanced idea of how and why C++ evolved the way it did (links on my publications page: http://www.research.att.com/~bs/papers.html. The second paper covers the design criteria and ideas for C++0x.
You said:
The bottom line: keep simple things simple (but remember that simplicity can be achieved by using high-level libraries); use abstractions when necessary (and even then, make spare use of it; follow good design principles and established good practices).
That’s sound advice, and the reference is good. Unfortunately, it is not easy to know when abstraction is beneficial and how much is “just right”. I would be a bit more aggressive about the use of classes and templates than you appear to recommend, but then I may be assuming a bit more experience. For a discussion of the use of abstraction see Bill Venner’s interview with me on that topic (http://www.artima.com/intv/goldilocks.html) that he entitled “The C++ Style Sweet Spot”.
注:Bjarne在最后一段提到的访谈也是最技术的一篇,非常值得一读,这里推荐荣耀先生的翻译:
The C++ Style Sweet Spot (Part 1: C-style, object orientation, invariants, simple interfaces). Interview by Bill Venners for Artima.com. September 2003.
Modern C++ Style (Part 2: Multiple inheritance, Abstract classes, multi-paradigm programming, and "resource acquisition is initialization"). Interview by Bill Venners for Artima.com. November 2003.
Abstraction and Efficiency (Part 3: Raising the level of abstraction, "programming is understanding", and the difference between premature and prudent optimization). Interview by Bill Venners for Artima.com. February 2004.
Elegance and other design ideals (Part 4: Aspects of software design, the importance of libraries, protecting programmers from themselves, the dangers of premature abstraction, and the essence of elegance). Interview by Bill Venners for Artima.com. February 2004.
--
1. 最近Feedburner抓取feed似乎出问题了,然而还有近200位同学通过Feedburner订阅了C++的罗浮宫(本来用FB的时候没预料到“墙”的问题,sigh~),所以,麻烦用FB订阅的同学转为用下面的feedsky订阅:-)
http://feed.feedsky.com/pongba
又或者你也可以直接订阅原始rss(因feedsky的服务似乎也似乎时有问题):
http://blog.csdn.net/pongba/rss.aspx
2. C++的罗浮宫已改为全文输出。
3. As Always,欢迎加入我们的讨论组—— TopLanguage( http://groups.google.com/group/pongba),自从 8月份建立以来,我们已经吸引了三百位同学,二千五百多条讨论,想知道我们讨论些什么,参见 TopLanguage讨论 精选[一], 精选[二], 精选[三],加入前 请看这里。