Hacker News new | comments | show | ask | jobs | submit login
C++ is a horrible language, says Linus Torvalds (gmane.org)
62 points by nickb 3728 days ago | hide | past | web | 60 comments | favorite



The whole exchange is great! Keep on reading the subsequent messages. Here's some interesting parts:

" The fact is, that is exactly the kinds of things that C excels at. Not just as a language, but as a required mentality. One of the great strengths of C is that it doesn't make you think of your program as anything high-level. It's what makes you apparently prefer other languages, but the thing is, from a git standpoint, "high level" is exactly the wrong thing. "

and

"And if you want a fancier language, C++ is absolutely the worst one to choose. If you want real high-level, pick one that has true high-level features like garbage collection or a good system integration, rather than something that lacks both the sparseness and straightforwardness of C, and doesn't even have the high-level bindings to important concepts.

IOW, C++ is in that inconvenient spot where it doesn't help make things simple enough to be truly usable for prototyping or simple GUI programming, and yet isn't the lean system programming language that C is that actively encourags you to use simple and direct constructs."


<i>"pick one that has true high-level features like garbage collection or a good system integration, rather than something that lacks both the sparseness and straightforwardness of C, and doesn't even have the high-level bindings to important concepts."</i>

That's a straw man. There are garbage collectors and "system integration" libraries for C++. The language doesn't lack for high-level bindings, but it also doesn't force you to adopt a paradigm. This flexibility is C++'s greatest strength, as well as its greatest weakness.

Personally, I find it more than a little ironic that a huge amount of the complexity of C++ comes from its insistence on remaining backwards-compatible with C. Linus may love the "lean system programming language", but it sure does bring a lot of ugly baggage to the C++ party....


"...but it also doesn't force you to adopt a paradigm. This flexibility is C++'s greatest strength, as well as its greatest weakness."

Lisp is mult-paradigm also. I think the difference is that Lisp has a philosophy. The paradigms fit together in a consistent way. For example, Common Lisp has an object system, CLOS. But they implemented it around generic functions, in order to keep the functional programming nature of Lisp intact.

Lisp will let you do pretty much anything. But it often gives you a "nudge" in a particular direction. I believe pg points this out in On Lisp; you can write procedural code in Lisp, for example, but the code flows a lot better if you write in a functional style.

C++ just seems like a kitchen sink language. Everything is in there somewhere. But it doesn't seem like the parts were designed to fit together in any particular way.


I agree with you about Lisp. I like Lisp; it's definitely more elegant than C++.

That said, C++ was designed to be resource efficient, at a time when the best Lisp interpreters were...well...less so. So, while C++ and Lisp both have OO, functional, procedural and metaprogramming techniques (among others), C++ has made some ugly choices to achieve efficiency at the same time.

For the record: I am not trying to get into a Lisp/C++ debate.


Now, why in the world would someone mod down my comment?

Honestly, folks...it isn't a criminal offense to disagree with Linus Torvalds. There are positive things to be said about C++.


I just read the whole thing... Linus basically says "I wrote it in C so idiots like you wouldn't (and couldn't) contribute".

Which is mean spirited and kind of an asinine thing to say, but so awesome at the same time.


That's not what he said. He said "I wrote it in C because C was the best language for the job. It's also nice that C discourages idiots from trying to contribute.".

He's right on both counts. I've always found using tools designed for smart people to be an effective way to cut down on the number of stupid people attempting to work on a project, but the main advantage is getting to use a good tool instead of a bad one.


Linus is hellbent on not working with "substandard programmers" and chooses his tools accordingly. Bad programmers are really counterproductive and he's damn brilliant for weeding them out so aggressively.

In his "I'm a bastard" post to the linux kernel thread in 2000, he lambasted people arguing for a kernel debugger. His argument, clear as day, says he doesn't want to work with people who depend on the debugger , he wants people to understand the code as a whole.

"Oh. And sure, when things crash and you fsck, and you didn't even get a clue about what went wrong, you get frustrated. Tough. There are two kinds of reactions to that: you start being careful, or you start whining about a kernel debugger.

Quite frankly, I'd rather weed out the people who don't start being careful early, rather than late. That sounds callous, and by God, it is callous. But it's not the kind of "if you can't stand the heat, get out the the kitchen" kind of remark that some people take it for. No, it's something much more deeper: I'd rather not work with people who aren't careful. It's Darwinism in software development."

Here, 7 years later, he applies much the same argument to C++:

"C++ is a horrible language. It's made more horrible by the fact that a lot of substandard programmers use it, to the point where it's much much easier to generate total and utter crap with it. Quite frankly, even if the choice of C were to do nothing but keep the C++ programmers out, that in itself would be a huge reason to use C."

"And limiting your project to C means that people don't screw that up, and also means that you get a lot of programmers that do actually understand low-level issues and don't screw things up with any idiotic "object model" crap."

Call him a prick, call him selfish, call him egotistical, the bottom line is he's in charge of a product that is much bigger, more complicated, diverse, mature, and successful than the majority on the planet. Smart hackers will get past their emotion and understand his principles are sound, proven, and successful.


It was also a uniquely useless comment he responded to. Imagine the alternate universe where Linus responds, "you're right! Git hackers, commence the rewrite!"

In a job interview, statements like Dmitry's are what I'd call a "leading indicator". NO HIRE.


- Yes, it takes a C++ expert to do C++ well. If you aren't an expert, you're going to screw it up. You'll either get mired in what I call "Fancy C++ Voodoo Magic" by over designing your code and doing weird template meta-programming without any real goal or just use the wrong idioms, or forget about some random subtleties.

- Sometimes you really do need to write systems software. In these instances, I'm still going to use C++. I won't claim that C++ is a great language, but at the end of the day, the benefits provided by C++ make it worth it. It would just be more footwork in C. Classes, RAII, STL, templates, type-safety are all worth it. But this is because I have already made all the mistakes and written lots of bad C++ that I'm now able to write clean, simple and elegant C++. I'd advise a newbie programmer against becoming a C++ expert. It's not worth the time and effort to learn all the stupid cases and to learn when to use which feature and to what degree to avoid falling into the swamp of C++. It's worth knowing C++ well enough that you can hack systems code though. I wouldn't say "only learn C and not C++ for systems hacking!"


I reverse engineer and audit systems software for security flaws (OS kernels, hypervisors, filesystems, drivers, and higher-level stuff like client-server and message passing systems). I've looked at a lot of other people's systems code. Most of it is C, not C++. It's mostly C on Win32. It's mostly C on Solaris. It's mostly C running in VxWorks. Most systems code is C.

Knowing both C++ and C, my counsel (worth what you paid for it) is that C++ is a waste of time for systems work. If you want to allocate a year of your life to minutiae, learn X86 runtime code generation; it'll help more with systems work, and you can write your own DSLs in C.


"It's mostly C" isn't an argument, it's an empirical observation. There are various historical and technical (ABI issues mostly) reasons to use C for kernels, hypervisors, filesystems and drivers. I'd still use C++ for all of the above, although a restricted subset if I'm writing a kernel, hypervisor, or driver. I would only export a C interface from my C++ code if it requires dynamic linking though (e.g., I would never write a export a kernel's API for device drivers in C++)

I also don't mean learning minutiae for minutia's sake. Most of my work has been on compilers and servers, and I'd gladly take C++ for these tasks. Why should I do the extra footwork to write it in C?

A sibling post mentioned LLVM. This is a great case in point. You should look at the GCC source sometime... it's absolutely atrocious. LLVM is on the entire opposite end of things, the code and design are beautiful. Hacking on GCC requires 80 pounds of body armor and a consultation with the local shaman. Hacking on LLVM is fun, exciting, and easy.

"Reload is the GCC equivalent of Satan." http://gcc.gnu.org/wiki/reload

GCC's internal garbage collector. Yes, they really wrote a garbage collector for a C app, and dealing with it is just as pleasant as you'd imagine. http://gcc.gnu.org/wiki/Memory_management


There's definitely good C++ code; the MIT PDOS Click router (http://www.read.cs.ucla.edu/click/) is another great example. But there's good Perl too.

I'd definitely use LLVM before I hacked up GCC.


> learn X86 runtime code generation

It's much easier just to embed LLVM.


That counts. LLVM. Better than C++.


"... Sometimes you really do need to write systems software. In these instances, I'm still going to use C++ ..."

So you write non-portable code?

c is still the language of choice for "portable" system work because c compilers can target lots of different systems. You cannot say this for c++. Not because of language deficiencies but limitations with the toolchain.

Wx faces the problem of using 10yo c++ features because of the lame nature of c++ compilers (Codingstyle Interview with wxWindows Developers, Steve Frampton, 2002) ~ http://codingstyle.com/index.php?name=News&file=article&...


This is just an outdated understanding of C++, unless you really need to target a VAX or something. I don't intend my programs to run on machines more than 10 years old anyway. A decade ago, the non-portability of C++ was a real concern.


Just target g++, which covers all major platforms. C++ is portable.

I can't believe all the pro C ranting. Do you people just enjoy typing? C++ is far more succinct. The same people agreeing with Linus here probably post elsewhere in favor of high level interpreted languages like Python over Java and C#.


Linus basically says that C++ has "inefficient abstracted programming models". Looking at the STL, you only see some very basic abstractions: vectors, lists, hash tables, sets, and others. These are very well tested, and extremely optimized. Anyone writing a decent amount of code will undoubtedly run into a situation where they need such structures.


Agreed. You would have to have to invest a considerable amount of time to beat the STL objects in terms of efficiency. I cant even think of a situation when you really could. Why try to reinvent the wheel? Seems like time wasted if you ask me.


The arguments I hear most frequently are the same ones that Linus jumps on in this thread: the syntax is obtuse, the code isn't portable, and the language isn't truly high-level (i.e. it doesn't have built-in garbage collection).

The first argument is (sadly) true -- C++ is ugly and complicated. A lot of that comes from the need for backwards compatibility with C (which isn't going to win any language beauty pageants, either), but a lot more of it comes as a consequence of the syntactic flexibility of the language.

The second argument is mostly bunk. A decade ago, it was difficult to find a standards-compliant C++ compiler; today, it's fairly easy. Sure, there are dark corners of the language where certain compilers get funky, but that can be said of FORTRAN 77 compilers, too. In general, unless you're forced to work with a old compiler, or an old, unmaintained package, it isn't very difficult to write cross-platform C++ code.

The third argument is just a straw man. Anyone who has read Stroustrup's book on the design of C++ knows why garbage collection and other "high-level" features weren't incorporated into the standard -- they didn't want to force users to adopt particular programming models or designs. Stroustrup has insisted that C++ be a flexible tool for many different types of programs and programmers; that attitude leads, somewhat inevitably, to complexity. But it makes me sad that so many people are bashing on C++ for not being "more like" other languages, when its biggest strength is probably its ability to mimic many features of those same languages, while still allowing for great efficiency.


C is beautiful if you're standing on a motherboard staring up at it. If you think mostly in terms of how hardware works, C is a clean, powerful language.

"The language isn't truly high-level" isn't the whole argument; which would indeed be a straw man. That's the main part that's tied to the "most C++ programmers suck" argument, though. He thinks the "pseudo high-levelness" of C++ encourages sloppy programming.

Also there's another argument in there: Object-Orientation is overrated and often causes as many problems as it solves.


Most programmers suck in every language.

If Linus' experience with C developers is that they are better than C++ developers, it's probably because he is familiar with the qualities of good C developers.


Here's the response from the thread:

LT> "You can write bad code in any language. However, some languages, and especially some mental baggages that go with them are bad."


Your third argument is fallacious. C++ is gradually incorporating everything you're talking about into the standard. Stroustrop has openly stated that lack of standardized threads were a mistake: you can't get much more environment-specific, model-specific than that.


Stroustrup was referring to the standard library, and he wasn't advocating the inclusion of threads at all costs.

C++ is still guided by the principle that you don't have to pay for what you don't use. That was the crux of my argument, and it continues to be true.


You haven't refuted Linus. You've explained why the world works the way Linus says it does. But the impact is the same.


to beat the STL objects in terms of efficiency

string s = "string literal";

vector<int> v = {1, 2, 3}; // C++0x feature

Any language with built-in string/array support will beat STL in initializing things, to start with. STL does dynamic allocation in these examples, in case you didn't know.


Are you sure about that? I don't really know the internals, but I would assume the implementation looks something like: Let the compiler put the array (of characters or numbers) somewhere where I can get them, and I'll take that pointer and keep it in my stack-allocated STL data structure.

Any references that say you're right?


The best reference is the source code.

Let's look at the string. In C/C++ there is no reliable and portable way for your program to find out whether some (char*) points to a constant string literal or not. So the only oprion for a dynamic string implementation is to always copy any data the constructor receives to somewhere else, normally to the dynamic memory. As a result, any initialization involves dynamic allocation and copying of data in C++.

At the same time languages that have built-in support for dynamic structures avoid this by creating proper structures in the constant segment. So a statement like string s = "abc" would do nothing but assign a pointer.

This is a huge problem in C++ and even C++0x doesn't solve it unfortunately.



I'm not convinced it's solving the problem I mentioned, but I'll try to figure out myself, since this becomes off-topic already.


Looks exactly like what was missing. Sweet.


You are certainly right, but I was simply comparing creating custom data structures in C vs. STL in C++ since that is what Linus was comparing. You are arguing that other languages which have built in static string/array support will be faster than C/C++ and I dont argue with that.


I think even in C or with C-ish programming with C++ you can achieve better performance (in return for some verbosity, of course).


Justify that statement with evidence. Why would you assume hash_map would outperform a C hash table, or vector outperform a C VLA?


The times you are likely going to be able to beat STL is if you:

1) Have a highly specific algorithm where you know your memory characteristics very well, or

2) You are doing lots of memory allocation/deallocation. For example, something like vector<vector<myclass>> will be nasty in STL.

Outside of that though it will be difficult. STL was designed with speed as the foremost objective. It is simply very hard to beat in MOST tasks (but not ALL). For example, Vectors dont do any bounds checking. Most STL vectors will have performance on par with a simple dynamically allocated array. Iterators are also not validated before accessing a container.

So I wont say they cant be beat. They certainly can. But how much is your time worth? I guess it depends on your objectives and how critical every ounce of speed is. I understand there are probably situations with some where this type of thing is life or death.


I think you missed the word "evidence" in my request. I could have predicted that you believed STL was faster. But "it's faster because it's supposed to be faster" is a weak argument.

Again I see people in this thread falling into the trap of conflating code reuse, a good thing, with C++, a dubious thing. Code reuse makes things faster, of course; it allows effort to be specialized. But C++ doesn't enable code reuse; it merely encourages it.


Here are some benchmarks on sorting:

http://theory.stanford.edu/~amitp/rants/c++-vs-c/

Besides that, custom C vs. STL comparisons would need to be done case-by-case. Admittedly, an all-encompassing statement "STL is always faster than C" is unreasonable. It depends entirely on the situation and what you are trying to do. I'm simply saying that it is very difficult and probably more time consuming than it is worth (for MOST cases) to try to beat STL in C++. When I used to do lots of graphics programming I tried (mostly out of curiosity), but I always ended up just using STL.

But maybe your experiences are different? Do you write your own arrays, hash maps, and sorting algorithms each time you use them? There are times when code reuse is A Good Thing. Like when the difference is negligible and it enables you to dedicate time to more valuable things, like building product features that users want. When it comes down to it, everything is always a matter of time.

Please explain what you mean when you say "C++ doesnt enable code reuse, it merely encourages it". Just curious..


He's not using "inline" for the C version, so it counts spurious function call overhead. He's also not holding constant the storage classes between C and C++; his C++ version arbitrarily gets to use optimal storage. This should be intuitive: bare C++ isn't faster than hand-coded C, and beyond that all you can compare is the quality of different libraries.

When I say "merely encourages", I'm trying to articulate the fact that most large C projects are composed of modules that implement different ADTs. Just because C doesn't call them "classes" doesn't mean that most C code isn't reusable.


Surely you're not implying that vectors, hash tables, and sets are hard to write in C.


OK, then I want you to write me an efficient implementation of Red-Black tree deletion, and do it within an hour.

(std::map and std::set are usually implemented with a Red-Black tree.)


What a silly argument.

(a) STL's map and set weren't implemented in an hour.

(b) Abstract data types (and, more generally, code libraries) predate C++ by decades.

Six years ago, I took over as lead dev for a product now counting and statistically modeling a significant percentage of all the packets traveling across the backbones of virtually every tier 1 ISP in the world. One of the first things I did there, coming off 3 years of C++ development, was to backport the STLport Red-Black tree, from the "map" template to an "rbtree.c" library.

My rbtree.c is faster than STLport's, and far easier to use. You don't need to read Meyers and keep a cheat sheet to avoid iterator invalidation to use it.


libavl. Next?


Eww. Better to use C++ than AVL trees.


http://www.stanford.edu/~blp/avl/

    * Binary search trees
    * AVL trees
    * Red-black trees


Oh. This is a library under straight GPL. You can't use it in non-GPL code. No wonder I hadn't heard of it before.

Thanks for the pointer, it's neat. I really like how my approach turned out; the STLport red-black tree is well done. Backporting it to C only took a couple hours.


maybe this will help you

Stroustrup: Well, one day, when I was sitting in my office, I thought of this little scheme, which would redress the balance a little. I thought 'I wonder what would happen, if there were a language so complicated, so difficult to learn, that nobody would ever be able to swamp the market with programmers? Actually, I got some of the ideas from X10, you know, X windows. That was such a bitch of a graphics system, that it only just ran on those Sun 3/60 things. They had all the ingredients for what I wanted. A really ridiculously complex syntax, obscure functions, and pseudo-OO structure. Even now, nobody writes raw X-windows code. Motif is the only way to go if you want to retain your sanity.

[NJW Comment: That explains everything. Most of my thesis work was in raw X-windows. :)]

Interviewer: You're kidding...?

Stroustrup: Not a bit of it. In fact, there was another problem. Unix was written in 'C', which meant that any 'C' programmer could very easily become a systems programmer. Remember what a mainframe systems programmer used to earn?

Interviewer: You bet I do, that's what I used to do.

Stroustrup: OK, so this new language had to divorce itself from Unix, by hiding all the system calls that bound the two together so nicely. This would enable guys who only knew about DOS to earn a decent living too.

Interviewer: I don't believe you said that...

source: http://members.safe-t.net/jwalker/programming/interview.html


Let's make it clear that that was a joke.


I heard "fake steve jobs" was conducting that interview.


Linus shouldn't talk about something he doesn't understand. He couldn't have found a better way to advertise his ignorance about C++ to the whole world than this.

He is telling the whole world that "Hey, here I am, you know, the guy who created the linux kernel, the best designed piece of software in the whole universe(don't listen to Tanenbaum though, he didn't learn OS fundamentals), so you better listen to me when I say that C++ _sucks_. Don't give me the BS about how so many large applications have been created in it, because they would have been only better had they been created in C(it's a magical language btw, solves _all_ your problems in the blink of an eye). If you go and read about people like Stroustrup, Sutter, Alexandrescu, Koening, Thomas etc, take it from me that they missed lot of their CS clases, so they don't know a thing about programming. How do I know? They use C++!"

Sage Linus at one point or the other has to wake up to the fact that he is not the guru of all things that is programming and his opinion of the C++ language is taken as seriously as that of my hair dresser.


I have must have learned at least a dozen programming languages in my time, and none was as difficult and as counter-intuitive as C++. (Compared to C++, Ada was simple.) I think C++ was just a bad idea, a clumsy attempt to merge two incompatible paradigms.

In classical imperative programming (e.g. C, Algol, Fortran, Pascal, and Basic), procedures contain and copy data structures. The heap primarily exists when unusual flexibility is needed, e.g. when the number of data objects you need isn't known until runtime. so you manage them with a global heap-based collection. Generally, you try to avoid using the heap, and where you must use it, you build an API around your collection to hide the nasty ugly details.

Compared with imperative programming, object orientation provides a kind of inversion of control. Instead of having procedures which contain and manipulate data structures, you have objects which contain methods (to handle the messages that other objects send it). Objects manage their own lifecycles and storage allocation. This sort of distributed control implies a level of abstraction well above concerns about storage management. Instances of subclasses tend to be larger than instances of their parent classes, but so users of these polymorphic objects are presumed to be above worrying about the storage they take up. But that makes us dependent upon that nasty heap -- is it any wonder that the vast majority of object oriented languages _presume_ automatic garbage collection?

The very fact that the C++ programmer is responsible for storage management implies that C++ objects are not to be visualized as independent and cooperating entities that manage their own lifecycles -- because then it becomes unclear as to who will have responsibility for cleaning up.

Systems programming is of necessity low-level; a reliance upon automatic garbage collection simply isn't appropriate for those kinds of problems. Therefore, instead of trying to add object orientation to C (and therefore an over-reliance upon the heap), I think we'd have been better off to begin by simply adding a strong, polymorphic type system. Then we could write systems programs with a manageable degree of genericity, without requiring every programmer to become a language-lawyer interpeting seemingly conflicting regulations, or an empirical scientist running experiments to determine what his programming language does in a given situation.

If we could then create easy hooks by which an object-oriented language could make calls to low-level subroutines written in that systems programming language, so much the better.


I stopped listening to linus after he layed into gnome.


Install Vista and that'll flip him. Flip him for real.


Ha Ha Ha Ha. So hilarious.


"Quite frankly, even if the choice of C were to do nothing but keep the C++ programmers out, that in itself would be a huge reason to use C."

What's not hilarious about that?


I think you were downmodded not because your post was wrong, but because it's essentially noise (I didn't downmod you).


Anyone see Linus's Google git presentation? That and reading various stuff like this shows he's a rude egomaniac.


http://www.youtube.com/watch?v=4XpnKHJAok8

I think he has a unique combination of mild autism, artistic stubborness and scandanavian directness. In the end he makes valid points and he sold me on trying git.

It is hard to tell if he's being serious or if he's just making socially retarded attempts at sarcasm.

Either way he's infinitely more charming than Mr. Zuckerburg...


It was a rude and egomaniacal comment that he responded to, if you think about it. But that's OK. I don't think Linus cares if you use his code or not.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact

Search: