There are plenty of reasons. As just one of them: C++ is unsafe by default. There's theoretically a safe subset, but there's no precise or consensus definition of that subset. There's no type-system or language support for helping you stay strictly within that subset (and requiring some kind of marker for if you don't). Often, the most obvious way of doing something is unsafe; for instance, in C++, arr[i] is unsafe, and you have to write arr.get(i) to be safe. (In Rust, arr[i] and arr.get(i) are both safe, and you have to write arr.get_unchecked(i) in an unsafe block if you truly want an unsafe indexing operation.)
Can you help me understand why locking C++ out of a kernel written almost entirely in C, and which receives huge volumes of new C code every year, wouldn't be an instance of making the perfect the enemy of the somewhat marginally better?
I would question the "somewhat marginally better" part.
(Please take all of this with a grain of salt, as I do not write "modern C++" in any professional capacity; its complexity has grown far beyond my knowledge.)
I think introducing C++ into the kernel (and getting value from it) would require effort on par with introducing Rust, to provide safer interfaces for things. It would also require a substantial combination of tooling, documentation, and convention, to define a careful subset of C++ for use within the kernel, and to the best of my knowledge that tooling does not already exist. The C++ code would also have to continue interoperating with the existing C code, which means that even if there were a tool to say "warn/error about C++ code that uses one of the unsafe bits that comes from C", the kernel likely couldn't use that without substantial additional integration.
And conversely, C++ introduces new potential errors that don't exist in C. The first example that comes to mind: if you use a C++ smart pointer, and do anything that gives you the raw pointer (e.g. &something->field, which is extremely common in kernel code), and put that in a data structure, and then let the smart pointer go out of scope, you now have a use-after-free vulnerability. In C, that would require explicitly freeing the object; in C++, there's no visible code associated with freeing the memory, and nothing in the type system tells you you've done something wrong there.
A sufficiently well-trained modern C++ developer presumably would not make such an error very often. But what about a large number of expert-level C developers who are attempting to work with modern C++?
Introducing C++ into the kernel would add a substantial amount of complexity, and I'm not at all sure that on balance you'd end up on "marginally better" rather than "worse". I'm not suggesting it couldn't be done, or that it couldn't eventually provide some improvements, but it's not clear to me that it's an obvious win.
For what it's worth, I think it's a moot point; it's really hard to imagine major new subsystems being written in C++, and not hard to imagine them being written in Rust. But if you're going to have a polyglot kernel, it seems pretty weird to exclude C++ if you're still accepting the majority of your patches in C.
I think that’s ultimately the question. Given C++ is not technically safer than C (as the GP points out), is it worth the complexity of adding it to the kernel?
I have to say though, most of my hesitation of looking at and trying to contribute to kernel is actually the development model. I think I’ve seen from Linus that it is purposefully obtuse to ensure only people who really want or need to contribute will do so. But now they’re pointing out that they’re having a problem attracting new contributors. Is that due to the language or the development and commit model?
Rust would be a huge improvement, but I don’t see how that alone would fix the contribution model.
I agree that C++ isn't meaningfully safer than C, but the kernel isn't a safe program. If the C kernel was moribund, that'd be one thing, but the opposite thing is true: the standard kernel programming language is C. Meanwhile, it'd be hard (not impossible) to argue that C++ is less safe than C, and there are other considerations besides safety.
(C++ in the kernel has been done before; the Click Modular Router, for instance).
But it can be far safer than it is today. I assume you’ve seen Writing an OS in Rust by Philipp Oppermann? The unsafe portions are very small compared to the safe: https://os.phil-opp.com/
I just don’t see why you’d include C++ at this point when there are far better options that would provide meaningful improvements in safety.
Simple: C++ is a much more expressive language than either Rust or C. That is to say, you can write libraries in C++ that are wholly impossible in Rust or C, that encapulate semantics and optimizations that cannot be done in any other language.
There are sound reasons why the highest-paying development in all fields is done exclusively in C++: finance, aerospace, CAE, HPC, telecomms -- all are exclusively C++. Rust is not a blip there, and C is entirely dead (except some aerospace and telecomms).
Safety is not the driving force in systems development: capability is. C++ is simply more capable than C or Rust, and Rust is very far from mature. Given competent modern C++ coding practice, safety is just not a problem, in practice.
C is a far simpler language and C++ is at least an order of magnitude more complex (and getting worse). Complexity is inversely correlated with safety.
Of course additional considerations (understandability, maintainability) are probably even more important in this case.
Having spent some time examining both Linux (written in C) and the Haiku kernel (written in C++) I'm far from clear that C++ is even "marginally better". More complicated is worse right?
A kernel like Linux invariably develops its own idiom that I think probably has more influence than any of the C++ syntactic sugar that you'd be allowed to use in that environment.
Do you have an example in mind of something you wish people did in Linux that they'd likely do with a restricted C++ dialect but not C?
Here [1] is one of Linus's more well-known rants about C++. It's in reference to the Git source, but I think most of it applies to his attitude towards using C++ in the kernel as well.
Just to be clear, I don't know that anyone in this subthread likes C++. I stopped writing in it in 2003 and I'm glad to be done with it. (I still adore C).
C++ is a Frankenstein of a language, can't really be parsed, so many idioms, nobody agrees on the common subset.
If there was a C++ totalitarian who ruled with an 'iron set of idioms, conventions and best practices' maybe 20 years ago and forced the world into his benevolent bidding - then C++ might be useful there, even if 'unsafe'.
The memory safety value of Rust is way overblown. That's an important feature but not 'the' feature. Most C++ programs are not dying from memory problems. Rust's value in everything else as well.
The biggest issue with C++ is it's an absolute atrocity -- an agglomeration of every feature under the sun, but half-built as many of those features can't possible co-exist.
I mean, for example, std::move doesn't move... anything. std::move "just" static_casts the receiver as a template<class T> typename remove_reference<T>::type&&. Not that any sane human knows what that means. The source object remains alive and potentially invalid. Who even knows? Certainly not the compiler. This is just one example. All of C++'s new features are built like this. And the old ones are just so fragile.
It's an incredibly dangerous, convoluted and absurd language, and every time I turn around it gets worse. It's time to leave C++ in the dustbin. It is an octopus made by stapling extra legs onto a dog.
I used to be a C++ diehard, but modern C++ is the reason I started learning rust.
I figured if I’m going to learn a bunch of new rules and idioms, I might as well do it with a language that has those things built in rather than bolted on as an afterthought.
When I tell people their Typescript React projects look like a steaming pile of unrecognizable shit, I get downvoted. My precious simple shitty JavaScript is destined to be a bride dressed up in the shittiest possible gown sewn together in a hodgepodge of programming ideas implemented with the shittiest hacksaw one could afford.
It’s really not, but alas, the great crimes you won’t know about until after the fact. A crime is happening in the JS community, and one day we’ll all be writing the same thing OP wrote about C++, an amalgamation, a monstrosity, but whatever, it’ll be too late.
Just wait until Rust (or lots of new languages) get mature and start getting pushed in weird directions by niche use cases.
In addition, languages always need to be seen improving in order to hold the attention of all the magpie developers. Who wants to use an old, stable language, amiright?
Everyone will want their own small syntactic sugar to make their own ideas more easily expressed in the language they are currently using. It is just part of the lifecycle of programming languages.
I am willing to predict that if Rust is still around in 30 years it will be unrecognizable to present-day developers, and newcomers at that time will decry it as 'an agglomeration of every feature under the sun'.
Don't let your feelings get in the way of your valid argument about C++.
The Linux kernel will eventually going use the FFI route from Rust and C someday, but it is no safer in both safe Rust and unsafe Rust according to this memory saftey assessment study that has Rust CVEs [0]
Much of C++ is inappropriate for a kernel. And defining which parts of C++ could be safely allowed would take so much time and bikeshedding that it's just probably not worth it.