* Linus Torvalds : http://lwn.net/Articles/249460/
* C++ Frequently Questioned Answers : http://yosefk.com/c++fqa/
Are there any good passionate pro C++ versus C arguments?
By definition, the people who write the "entertaining" rants against C++ have an axe to grind. The people who like C++ just silently use it, and feel no need to write advocacy blog posts for the language. Even if they were to blog about it, it would be about as compelling as someone advocating for their favorite brand of screwdriver. Like it or not, C++ is the incumbent, and it's neither interesting nor fun to read someone advocating for the status quo.
Whenever you find yourself arriving at an opinion about a programming language solely from rants that you read on some dude's blog, please keep in mind that you're probably being most heavily influenced by the very people least qualified to teach you anything useful about the language. The internet is filled with useful articles about C++, but you don't remember those. You remember that Zed Shaw couldn't figure out how const works in C++, and once wrote a funny email about it.
Indeed. At my last job, working on trading software, we had around 35 maths or physics PhDs working on a C++ application. A few had personal blogs (cats, children, steam engines, etc) but as far as I am aware no-one there argued on the Internet about which language was best. C++ just doesn't attract self-publicists the way Ruby seems to.
My impression is that there is a very high startup cost with C++ to getting it working on the platforms you want to support and picking the subset that isn't going to screw you. Once you get over the hurdle, the improved memory management (I agree with the post Zed is ranting in response to) starts to pay dividends.
Don't the boost guys say that now C++ is the most powerful programming language?
source?
My own view: I'm not in love with C++, but it's not nearly as bad as everyone makes it out to be. Most of the arguments I hear against C++ are the same tired things I've heard hundreds of times. They all have a grain of truth, but nothing so bad as to condemn the language.
C++ is as bad as they say it is. It is horrible, it is the worst language in the world ... except for all the other (a la Winston Churchill and democracy). The horrifical complexifications of C++ are just terrible, yet every one of them has a reason behind it. And also, the horrifical complexities are a bit more optional than the horrifical complexities of, say, Java. There isn't another language that has both the large-scale modularization given by OO and low-level efficiency of direct pointer manipulation and other C features. You get a vast library of available free code and a huge number of available tools to boot.
There is no other language for crafting large-scale, high performance tools. Java and C# can be just as fast but even fast Java has even greater verbosity overhead. And the scripting languages are great yet their resource overhead makes up for their compactness.
C++ is definitely a language of "big design". "Thinking in C++" is a mistake. You should think in your design and implement in C++. Unlike C, C++ seduces people to take the code for the design.
In any case, however flawed, the thing occupies a niche no other language can. I'm sorry.
http://warp.povusers.org/grrr/HateC.html
http://warp.povusers.org/grrr/cplusplus_vs_c.html
The guy has some fun rants in general.
Edit: Oh yeah, and this one, responding to Linus' rant.
http://warp.povusers.org/OpenLetters/ResponseToTorvalds.html
* C++ circa 2000 (before mainline g++ could handle Alexandrescuisms) is significantly different from C++ circa 2010, albeit in ways that probably upset Shaw even more (the more central role boost has taken, the more "expressive" templates have gotten, don't call me on any of this stuff).
* C++ std::string is an abomination, but you can always just do what I've done and what lots of other C++ programmers whose code I've read have done: just use char* and a simple string library (or a custom string class).
* Ditto for stream IO, which is a huge C++ misfeature but which is also pretty much irrelevant (I know of no part of the standard C++ library outside of things that explicitly support stream I/O that rely on you using it).
* I don't get the POSIX argument at all; just call the POSIX functions, they work fine. Nobody mandates that you use (say) ACE_wrappers to do systems programming.
* const-correctness may be another misfeature (I know I make fun of it), but the point isn't hard to see: if you take the time to const-correct your code, the compiler will spit out errors that would have otherwise been runtime faults.
One problem with const-correctness is C++ uses "const&" to mean two different things: it could mean either a reference to a persistent object you're not allowed to change, or it could refer to a temporary object which you're prevented from changing because the changes will disappear. The problem is it conflated access control with lifetime. It would have been better if there were a "temp" keyword - although the last thing C++ needs is more combinatorics of type decorators.
On the subject of consts, though, C++ simply enforces const correctness more, but doesn't the same criticism of confusing const apply to pointers in C as well? You can just as easily declare a "const * const" in C as in C++. So I fail to see why Zed Shaw writing something in C gets him away from that "problem", unless he doesn't write const correct C.
The fact that it's C++, where the prototypical user believes that they shouldn't pay for what they don't use just makes things worse. Everything being optional means there can be very few synergies in language or standard library design, because if feature A needs feature B to work, people who want A but not B will complain. C++ "chooses" either by omitting both A and B, or creating some low-level error-prone features and hoping users won't chop off too many fingers trying to build their own incompatible versions of A and B. An ill-designed misfit language is all but required by the dynamics of the situation.
If you do like const (which I do) then you can put it in pretty much everywhere, except if you are dealing with a library that isn't "const correct", but then a bit of type casting will save the day.
That's a big advantage of lots of the C++ features - if you don't like them you can often just ignore them.
For those with a slightly broader perspective and an inquisitive mind, perhaps you should take a look at at the Reason C++ framwork, specially if you have never seen C++ in its most pure uncomplicated OO form.
Reason is a C++ framework that ive been writing for about 8 years, which aleviates many of the sources of pain highlighted in this discussion. Writing code with Reason is much more like using a dynamic language, with a full library like Java or .Net.
It supports raii, but doesnt use exception handling and doesnt bother with const nonsense or over the top inheritance restrictions. In fact pretty much everything in Reason is public and designed to be derived, modified or enhanced.
It has generic programming features, but doesnt force you to write everything as templates (a classic mistake that the standard library makes). For example, you can have an iterator of int's without caring what the underlying container type is, so your code and algorithms can actually be generic, not just infectious templates.
Unlike a lot of C++ frameworks and libraries, its not specifically focused on networking, or a few esoteric template classes or collection libraries.
Reason is a fully featured systems programming framework with a complete interface to all the usual posix api's and everything else you would expect from a modern language. It has strings, regexes, streams, parsers, sockets, threads, filesystem, encryption, encoding, xml, xpath, collections, time and date, sql (mysql, postgress, sqlite), http (client/server), smart pointers, formatting, logging, and much more.
But the features are perhaps not as important as how it is written. It is simple, and very object oriented, everything is designed to work togeather cleanly and obey the principle of least surprise. Just like Python and Ruby, Reason allows you to do a lot in a very small amount of code.
So if your wondering how you can have the simplicity of C, with just the good parts of C++, heres your answer.
I think it is so interesting the mentality of static typing people. I would much prefer handling the few resulting run time faults than having to stuff with my code with const.
Anyway, there is no guarantee in C++ that something that compiles with all consts in the world will not throw a segfault at run time in the least expected moment...
Of course, one problem with C++ (and, to a lesser extent, C) is that many of those subtle correctness issues are direct results of the type system in the first place. Go figure.
However, to support what Zed is saying, Scott Myers (of Effective C++) was astonished about some of the things done there.
C++ doesn't follow the principle of Least Astonishment in any way that I can think of. And that is not good.
It's not exceptional because nothing of the points he raises are anything but a re-re-rehash of the same old tiring arguments that have been raised against C++ for 15 years or more.
It's not good because the examples he makes are straight up wrong or so vague as to be useless. His 'const' example is jibberish and the line about adding two integers with templates doesn't make any sense whatsoever. I guess the response to this would be that these points were exaggerations, mere literary style figures, which is fine. But it does take away from the quality of it as a serious post.
And finally it's not a critique. A critique implies some level of sophistication, an honest attempt to understand something and providing well thought-out arguments against the trade offs that were made in the design, or different viewpoints on fundamental issues. This is just a rant, touching on some of the more superficial shortcomings of C++ that are easily worked around and that for the most part haven't hampered tens of thousands of C++ programmers to use the language successfully for 20 years. A rant, yes. Venting, OK. But a critique, this is not.
In other words, C++ is great until something else has to call it. Then you're hosed and end up wrapping everything in C anyway.
The problem with V8, as with almost anything, is it doesn't support well threading and its GC can be a bit unpredictable like any other automagic memory management interpreter. But even so, there are ways to control it.
I certainly relate to what you wrote because I used to be a C++ dev in mid-90s (wintel, shivers.) But if you have some time, have a look at V8 for developers. It rocks. Also the newsgroup has a great community.
http://github.com/dennisferron/LikeMagic
Currently there is only an Io backend, but the library is designed so that the same C++ bindings can be used with multiple different backend languages. It's like Boost::Python on steroids.
And there is also Boost.Python.
However, if I had not been given the style guide and a more experienced reviewer to tell me right from wrong, I would be incredibly frustrated with the language. C++ is complex enough that a book probably isn't enough - you either need a mentor-type person or a very clean open source project to study.
[1]: http://google-styleguide.googlecode.com/svn/trunk/cppguide.x...
The novice programmer looks at the code and sees bit, bytes, pointers and functions. The advanced programmer looks at the code and sees class hierarchies, design patterns and frameworks. The master programmer looks at the code and sees bit, bytes, pointers and functions.
Before mastering C, bits are bits, bytes are bytes and pointers are pointers. While learning C, bits are no longer bits, bytes are no longer bytes, and pointers are no longer pointers. After mastering C, bits are once again bits, bytes are once again bytes, and pointers are once again pointers.
Why is it that C programmers bitch about C++, but C++ programmers don't bitch about C?
Lately, I've been using [Jansson](http://www.digip.org/jansson/) for JSON support in C. Wonderfully simple and fast. Also, [zeromq](http://www.zeromq.org/) for everything: logging, sockets, messages. Hoorah. F@&# yeah.
Please stop confusing the language with the APIs or the available libraries and features of the language.
This sounds simple, but it's profound: simply because you can do something, that doesn't mean that you have to do it that way.
To use Zed's example, let's say I'm hacking around a lot of strings. What's wrong with rolling a string class, adding a member or two? You only have to carry around a bunch of nonsense if you want to. If you don't want to use templates and strings and such, don't use them.
This is another in a long line of articles that go something like this: We did X in this certain way, and boy did it suck. Therefore all of X is the devil's work and will destroy civilization.
You can put about anything you want in for X. It's like a (oddly enough) template engine for writing blog entries.
You should go through stages in your career, with just about any X. Stage one is that you are ignorant. Stage two is that you've tried it. Stage 3 is expertise. Stage 4 is hate, and Stage 5 is grudging acknowledgement that parts of X are okay for certain situations. You realize that yes, X is done poorly maybe 99% of the time, but lots of smart people worked on it and there are some little gems in there that are useful from time to time.
Looks like Zed is stuck on Stage 4
Throw away the templates, throw away all the library stuff you don't like -- is there a reason to make a class and wrap some things? If so, you can do that in C++. You can't in C. It's a very simple question, and it has nothing to do with any of the things Shaw is going on about.
The fact that it's 2010?
A language and its standard library are theoretically different things, but in any practical sense, the choice to use a language carries with it the choice to use its standard library. Additionally, the way the standard library is usually reflects constraints placed on it by its language. Java, for example, has a verbose and ceremonial standard library, and that's not a coincidence.
There may be a larger argument about whether the various standards bodies have so complicated C++ that it's become unwieldy -- the comment about exceptions in destructors has merit.
But that's not the argument he was making.
Good programmers are good because of the things they don't do. It's the guys who want to use every feature and library that are often the ones creating the disasters the rest of us have to maintain. So yes, the features and such of a language can hurt. But that's true of just about any language save some of the hardcore functional ones -- C++ maybe more so than the rest. Being a coder using modern languages means judicious use of complexity. Simple is almost always better. Which is exactly where he's coming from, he just takes his argument too far.
In fact, one of the things C++ teaches you early on -- or you suffer all sorts of pain -- is when to abstract, when not to, when to use libraries, when not to, and the dangers of frameworks. It's the very fact that it's such a complex monster that forces coders to keep it simple, stupid. You don't get that kind of thing out of the box in something like Java. This is more bad than good in terms of delivering solutions, but it also is not all bad. It has merit because it trains programmers about the kinds of disasters they can make. If you can write good, easily understood and maintainable C++ code, I can trust you with about anything. If the first thing you do is jump in the swamp where all the alligators live simply because you can -- templates, large inheritance trees, etc -- then probably not so much.
C++ has many string types because each string type has its strengths and weaknesses. For instance, QString is a fully-featured and Unicode-aware string written in C++ that I use most of the time.
std::string is good for most things. What are your specific issues with it?
That's less true when talking about C/C++ than other languages. C/C++ are quite often used in embedded systems, which often have problems with dynamic memory allocation, code size, etc. This means that many embedded systems don't use the standard library, or only use portions of it.
Yes, you can. Object orientation is a property of the program, not the programming language. Pretty much every time I crack open C now, I'm writing Object-Oriented C.
(Also, immutability is a property of the program, not the programming language. Etc.)
You: language = base syntax + semantics Most: language = base syntax + semantics + common idioms + standard library + popular libraries
The problems is that you usually target a subset of C++, and two different company targets different subsets. This produce fragmentation and is not good.
Can this be solved/simplified? ages ago someone proposed an embedded C++ standard, and we have compilers in the embedded fields that support this stardard. Why it does not succeeds? everybody wanted a different subset of C++.
Probably just a tongue in cheek comment, but I wonder what he meant.
"LISP" is a convenient red-herring to throw into PL diatribes; it shows the speaker has some authority since he is "aware" of Lisp, and the glowing and mystical connotations that this, vague, awareness carries.
I'd pretty much agree with Zed's rant, that C++ often isn't worth the bother, unless you have a project that specifically requires C++ features, and you have a development team that can actually write solid C++.
Maybe I'll call this Jonathan's axiom, but if your team doesn't have enough experience to write in a Lisp-y (or any other genre such as ML-y) language, you probably shouldn't be messing with C++ either.
Not many people that say they can write C++, actually can.
The result is that you will rarely find programmers that understand C++ fully. I have seen a lot of awful code that uses C++ as C with classes, badly. Usually, classes and functions have been written with so little understanding of encapsulation that refactoring is painful. And for properly written C++ programs and libraries, it's usually hard to find people to maintain/modify it.
On the other hand, it is also hard to find good ML/Haskell/whatever programmers. And lots of people get away with writing ugly Python or Ruby code.
This is triple compounded when you only have to do C++ occasionally. I've never even got close to the point of looking at something like const *const char & and reading it like it was something normal like others seem to do.
That's right on the money. I can find a subset of C++ that I like and that I could program with, but that assumes that I'm not collaborating with someone and that I don't have to use C++ libraries (It's not just the code, it's the APIs, too). The latter is almost worse. I could imagine a company that has some rather strict standards, where the C++ development environment doesn't suck completely. Google's style guide seems to indicate that they might be one of those companies [1]. Much more likely you'd have to work with something like MFC, VLC or the complete boost hodgepodge.
And Zed is right when he's talking about the template meta-programming fad. I haven't seen any project where the pros outweighed the cons. And yes, I've read Alexandrescu.
People often say that you need all those features to build large applications. Which reminds me a lot of the "Doctor, it hurts when I do like this!" joke…
[1]: http://google-styleguide.googlecode.com/svn/trunk/cppguide.x...
I constantly get teased by friends about my british spelling s of common words.
#include <vector>
#include <string>
#include <iostream>
typedef std::vector<std::string> Strings_t;
Strings_t split(const std::string& string, char onChar)
{
Strings_t splitted;
size_t lastSplit = 0;
for (size_t i = 0; i < string.size(); ++i) {
if (string[i] == onChar) {
if (lastSplit != i)
splitted.push_back(std::string(string, lastSplit, i - lastSplit));
lastSplit = i + 1;
}
}
if (lastSplit != string.size())
splitted.push_back(std::string(string, lastSplit, string.size() - lastSplit));
return splitted;
}
int main()
{
Strings_t strs = split("$$qqqq$$$w$$$eee$$a$d$$$$$", '$');
for (Strings_t::const_iterator s = strs.begin(); s != strs.end(); ++s)
std::cout << *s << "\n";
return 0;
}The point is: in C++, there are so much things.. It's like a fuckload of thousand of features to satisfy everyone. How the fuck can there be no split? Ruby, split, python, split, java, split, php, split, C# split, C++ -your-20-lines-function-which-only-support-splitting-on-a-char-but-not-on-a-string.
Edsger Dijkstra is Masahiko Kimura
John McCarthy is Yip Man
Paul Graham is Bruce Lee
Steve Jobs is Fedor Emelianenko
Linus Torvalds is Mauricio Rua
Bill Gates is Brock Lesnar
Steve Ballmer is Eric Esch
David Heinemeier Hansson is Anderson Silva
Guido van Rossum is B.J. Penn
Sergey Brin is Antônio Rogério Nogueira
Lawrence Page is Antônio Rodrigo Nogueira
P.S. On the subject of format strings vs. cout and the "<<" madness, C++0x's variadic templates will allow a type-safe printf. So hopefully in the future we WILL see C++ move back toward format strings, but without loosing the type safety. It also gives the possibility of instead of having to remember to use %d for ints and %f for floats, we could just use format strings that use {1}, {2}, etc. as format string placeholders, the way C# does. Freeing you from having to specify in the format string what the type is is something C++0x type-safe-printf would allow you to do that you could never do in C.
f() {
LinkedList list;
populate(list);
use(list);
//forget
}
Freeing the list elements is done in one place only, in the destructor of LinkedList. In C, you have to call some kind of free function in every single place a LinkedList is used. The burden of managing memory is on the user of a library, not on its creator. I don't think this is enough to justify using C++ though.I understand that the language cannot express it, and that's why other languages (such as lua) do it the right way - immutable strings all the way, or at least by default (NSString)
Qt, wxWidgets, LLVM, boost
Hopefully we have IncrediBuild at work, and we don't have to deal all the time with such huge frameworks.
After my C++ period, I did a major project for myself and just used C - like a breath of fresh air after C++
In all my years using C++, I think that the only good applications where C++ made sense was in Nintendo and PC game development at Angel Studios and some VR development for Disney and SAIC. Everything else that I did in C++ should have been done in different languages.
There is a whole entry in Exceptional C++ Style (or another Herb's book) that says how much std::string sucks and how you can write an equivalent extremely quickly.
Anyway, don't like std::string ? You can use std::vector in place very easily, that's a well known trick (thanks to the guarantee that &v[0] returns a pointer to the data if v is a vector).
He talks about references but he seems to ignore the capability of C++ to offer perfect forwarding which enables you to greatly increase performance and memory usage and that's very difficult to mimic in pure C.
There's a lot to write about inaccuracies in this post actually, but what the point? People who hate C++ will discard them and people who love it already know it.
I tire of reading posts from people who didn't like a language for whatever reason and try to rationalize it.
C++ OO can be done to really abstract the application but still be very manageable and simple. Also C++ is a game industry cornerstone. I think game code in C is actually harder to consume that game code in C++.
C++ brings a lot of heavy-weight machinery to the table but the best part is that you don't have to use it. If you just want to write C but desire templates to reduce the amount of writing you need to do then so be it, write C-with-templates!
My big beef with the language is mostly due to the legacy crud it is saddled with in the C preprocessor. Many of the build time issues I find myself suffering with are because of people, for example, including Windows.h a) in the first place and b) not defining WIN32_LEAN_AND_MEAN. Junior (and senior, for that matter!) developers seldom know how to properly structure their code so that their iteration times don't plummet.
If you have some reasonable self-control, it is quite reasonable to use C++ as a small superset of C.
And most exception problems are solved with RAII. If you're using RAII, then you won't have memory leaks when exceptions arise.
Oh noes! I have to handle 10 requests a second!
Take a look at the SWENG-gamedev mailing list for some of the performance issues that people face in games and game tools.
/pissing-contest
Note: obviously this is not an argument against C instead of C++. It's more to forestall the meta-discussion.
One of the best examples is Informix RDBMS which was acquired by IBM in 2000. And the second best is... JVM. ^_^
And now I have tea to clean off of my monitor and keyboard.