As other's have stated, that is just Linus's opinion, which he is entitled to. It's also even understandable given his position managing all of the Linux kernel and git development work, and the large number of people who contribute (or try to anyways...) If you don't want people to blow their damn leg off, don't give them a shotgun (http://programmers.stackexchange.com/questions/92126/what-di...).
That said, this absolutely doesn't mean that you CAN'T do systems level programming in C++. I've actually done real RTOS and motor control work on a small embedded platform that went in a robot using C++! This is in an actual shipping product too, not just a hobby project...
As Linus said, it's definitely easier to come up with something inefficient in C++, and you do have to limit yourself to a sane set of features. That said, I think some of the things C++ brings to the table can make development a lot easier without sacrificing performance as long as you have a disciplined team and sane coding guidelines. But what makes sense for a personal project or a small team may not make sense for a larger project, and while I think Linus is justified in his opinion, you definitely shouldn't take it to mean that you CAN'T do systems programming in C++.
> as long as you have a disciplined team and sane coding guidelines
Is it not possible at all anymore to just hire people actually understanding what they are doing? Or cargo cult is here to stay?
I am sorry - please don't take that as a personal attack, but explaining people that C++ can actually be used in OS development by mindlessly sticking to some rules doesn't seem a way to me... but rather a counter-argument to what you said yourself.
It's more that certain features can be way more expensive than they look.
e.g. say you're working on an embedded system, and you want a string, so you do:
std::string s = "fnord";
At first it seems to work fine --- but you firmware image's RAM requirements have just gone up by 32kB, and a week later there's a crisis when adding another feature causes the system to stop linking because the RAM address space is full.
What happened is that std::string uses the heap to store the string data, so adding the line above caused the linker to pull in all the heap code and allocate a 32kB block of RAM to put the heap in. Because previously, the product wasn't using a heap: it was using static memory allocation throughout.
That example's contrived, but only a little. I've done the must-avoid-dynamic-memory-allocation dance many times in real life. (I've also discovered that printf() requires a raise() implementation on some platforms.)
A more realistic one is that embedded platforms typically have RTTI turned off, which means no exceptions, which means no throwing exceptions from constructors, which means two-phase construction throughout your program and you have to be really careful about which bits of the STL you use...
It so happens that I have been working in OS- and low level areas for many years, and independently am also a pretty early adopter of C++. I have a reflex of routinely giving a quick glance to the link map, and am frequently dumping assembly for areas of code I have doubts in.
All this to say that reading 'it seems to work fine' in the context of OS development kind of provokes a skin reaction in me.
In your string example (and in RTOS/C++ programming in general) couldn't you just change the default allocator to not use heap memory ? Then continue using std::whatever ? of course you'd have to keep a very close eye on your memory pool, but wouldn't this be one way to solve the problem ?
No No No! Don't apologize, its a great question! And to be fair I'm absolutely against "cargo cult" programming, and my point was actually that when you are doing C++ in this type of environment, you can't always stick to a hard set of rules or the conventional wisdom. When I say guidelines, I mean just that, and not a rigorous law you MUST adhere to.
As an example: When I was working on a project for a very constrained embedded device, we needed to get some extra man-power on our team for a few sprints to help out with some functionality. One of the pieces of our system was a "debug console" I had written that allowed some interactivity with the system over a serial port. The new guy was a very sharp engineer, but he typically worked on higher level stuff than we were doing. He wanted to add some functionality to the debug console, and dutifully started writing stuff in using the C++ string handling libraries. And consequently he blew our stack budget, and we ended up very quickly rewriting part of it together.
Now, the point is he wasn't doing anything using some crazy STL functionality or Boost, and he was doing the "right" thing by handling strings using the Standard Library functionality. What we had to do for our system was actually bend the conventional knowledge ("Don't write a string handling library yourself"), because we knew exactly what we needed, and exactly what resources we had.
So perhaps I could have phrased my point better. When I say "have a disciplined team and sane coding guidelines", I don't mean a team that codes by the book, I mean a team that knows what it is doing, and knows when the rules are meant to be bent. In our case sane coding guidelines meant we did things that were against the conventional wisdom, but they were sane, because they were justified in our case based on our engineering analysis. We were certainly open to breaking / changing these guidelines but it had to be justified. (And in fact our 'guidelines' were less a set of rules about how you needed to do every last detail, and more of a set of project specific "design patterns" and a large set of lessons learned in a shared wiki page which described issues we had run in to, and justified certain design decisions that were made)
(Edit: Other examples included disabling RTTI, and completely disabling and disallowing the usage of C++ exceptions to write our own error handling. Against the common advice to use what the language gives you, but made sense for our application)
Again, no need to apologize! I could have made my point clearer, and I hope I did, but please feel free to follow up with me! I'm always looking for ways to improve :-)
Ha. You posted this while I was writing my answer, and I see you (very nearly) used the exact same pair of examples that I did. This is possibly a hint as to where the pain points are...
Haha, I was just about to reply to your comment with nearly the same thing! I think one day I may need to do a book on C++ for embedded folks. Chapter 1 will be "Please don't use std::string!".
Could hold true to the HLL guys as well. I seem to remember at least a couple of performance analyses of apps in a High-Level Language where string concatenation was killing performance.
Easy to do. Tough to always remember the impact of what's going on under the hood.
HLL's (at least those which have a VM) often try interesting techniques to combat this, since string handling is so often a performance problem (it's a performance problem because they often make it relatively painless to manipulate strings, at least to the point where it's not obvious you may be doing something really inefficient). It's interesting if you follow the development of a language while it's being developed, you can usually see a few of the techniques they've used come and go. Starting with simple string handling, then global shared copy-on-write strings, then ropes, possibly a fourth weird representation, and likely back to one of the prior, simpler models.
At least, that's what I hazily recall from the long, jumbled Perl 6 history, but that includes a few changes to the language and multiple VM's and multiple string handling regimes per VM, sometimes.
Thank you, I get your point. Re-reading it, and other comments here, I am getting reinforced in suspicion I already had for some time -- people don't do operating systems in C++ simply because they cannot hire big enough teams of C++ developers skillful enough to code in an OS environment.
That said, this absolutely doesn't mean that you CAN'T do systems level programming in C++. I've actually done real RTOS and motor control work on a small embedded platform that went in a robot using C++! This is in an actual shipping product too, not just a hobby project...
As Linus said, it's definitely easier to come up with something inefficient in C++, and you do have to limit yourself to a sane set of features. That said, I think some of the things C++ brings to the table can make development a lot easier without sacrificing performance as long as you have a disciplined team and sane coding guidelines. But what makes sense for a personal project or a small team may not make sense for a larger project, and while I think Linus is justified in his opinion, you definitely shouldn't take it to mean that you CAN'T do systems programming in C++.