4 ms·
I think that his comment about "inefficient abstracted programming models" is probably the more pertinent one here. One important factor to consider there, and
by mumblemumble 5y ago
I think that his comment about "inefficient abstracted programming models" is probably the more pertinent one here.
One important factor to consider there, and for which Linux is wholly unlike the vast majority of other projects, even system projects, is that the userbase is just massive, and includes a lot of the world's infrastructure. That results in a rather different cost/benefit calculus around abstraction/performance tradeoffs than the ones for which object-oriented and functional programming were designed.
For example, I think that it's probably good for all of us that there's not really a whole lot of dynamic dispatch happening in the Linux kernel. I would generally prefer that my syscalls keep pointer chasing to an absolute minimum. But I'm hard pressed to imagine how a C++ style that avoids vtables like the plague could really have that much to offer over straight C. And it would simultaneously put extra code review pressure on the kernel team, since they would have to carefully watch to make sure contributors aren't introducing such things.
Similar concerns apply to Rust, mind. But it's much easier for me to see how Rust without trait objects could still bring something of value to the table.
- jeffbee 5y agoThe linux kernel is crawling with dynamic dispatch, but because it is in C they are the most inefficient dynamic dispatch mechanisms possible, with arrays of function pointers populated at runtime that 1) the compiler can never optimize, because they aren't visible at build time, and 2) that have been the causes of numerous vulnerabilities, because it's not always obvious at commit/review time that the author has screwed up the assignment of function pointers to dispatch slots. C++ would be a huge win all over the kernel, the only barrier to it is Linus' ignorance.
- kllrnohj 5y ago> But I'm hard pressed to imagine how a C++ style that avoids vtables like the plague could really have that much to offer over straight C. unique_ptr / shared_ptr alone would be a massive upgrade over straight C. Simply being able to enforce ownership would be huge. So would just having namespaces. Things like move semantics, static_assert, and constexprs would then be the cherry on top. There's also public/private fields, friend classes, etc... to keep people from accidentally poking things they shouldn't be. C++ is so very much not just "C with vtables." But C++ has a reputation, deserved or not, for being overly complex. And ultimately Linus chose the devil he knew over something that by all accounts would have been better. Nearly every other large C project has moved into C++, even from other staunch defenders of C like John Carmack eventually relented that C++ was better for large teams. Rust gets to hit the reset button here with a fresh reputation (and some extra safety & cool tricks), and Linus' views may have changed over time.
- tialaramex 5y agoC++ has a bunch of principles that Linus disagrees with. Actually some important C++ people aren't sold on them either, but too bad, they are principles of C++ and so you're stuck with them in C++. Examples include exceptions as the one true error mechanism, and the use of implicit allocation. Rust doesn't have the former, and Rust's core doesn't have the latter (but std does), one of the stipulations from Linus when this began was that Rust for Linux needed to ensure it didn't sneak in implicit allocation. Thus, while a beginner's Rust program might have text += "Some more stuff"; you won't see that in the kernel -- because it won't compile, the core::ops::AddAssign isn't implemented on these string types in the kernel because it's implicit allocation. As to move, the move semantics in C++ are really awkward. They're a nice optimisation of course, which is why they're provided, but you would not deliberately do it that way in a language which had move semantics from the outset, as demonstrated by Rust. To make move work with existing C++ software it has to "hollow out" objects when they're moved from. Rust needn't do that, if you move a Foozle from var1 to var2 in C++, it must carefully hollow out the Foozle in var1, because in C++ var1 will eventually get destroyed, so its contents must be valid and safe to destroy. If you move the same Foozle from var1 to var2 in Rust, the Rust compiler knows you moved it, so, it's gone, var1 won't get destroyed and no further attention to it is needed.
- kllrnohj 5y ago> Examples include exceptions as the one true error mechanism, and the use of implicit allocation. -fno-exceptions is very widely used and non-throwing variants of basically everything exist as a result. That's not a reason to avoid C++ in the kernel as a result. Especially with how heavily Linux already relies on GCC C extensions, there's obviously no hangups on being "strictly standard compliant." Not have exceptions ever been C++'s "one true error" mechanism ever. For example see iostream: https://www.cplusplus.com/reference/ios/ios/rdstate/ https://www.cplusplus.com/reference/ios/ios/rdstate/ C++ is not, and never has been, anywhere near that dogmatic. As for the rest of your points, you seem to be arguing Rust is better than C++. But that's not really relevant to why C++ was rejected before Rust even existed. I do think Rust is even better than C++, but I also think C++ is a huge improvement over C, especially for large codebases.
- jandrewrogers 5y ago> But I'm hard pressed to imagine how a C++ style that avoids vtables like the plague could really have that much to offer over straight C. I don't follow this argument. In my experience, use of vtables is relatively rare in modern C++ development even when you aren't trying to avoid them, many of which are elided by the compiler anyway. Regardless, in these infrequent cases it is straightforward to code equivalent functionality without vtables, since it is syntactic type-safe sugar over the code you'd have to write in C anyway. They are like C bitfields in that every systems programmer knows how to implement the equivalent functionality manually for cases when the language feature is underspecified for the purpose. Modern C++ without vtables is only marginally different than modern C++ with vtables, the code you'd write and the features you'd use would be nearly unchanged.
- int_19h 5y agoIn fact, most of the C++ standard library doesn't have virtual methods. It's also not a coincidence that the areas that feature them most prominently (iostreams and locales) are widely considered to be very dated designs that weren't particularly good to begin with, and didn't age well.
- formerly_proven 5y ago> For example, I think that it's probably good for all of us that there's not really a whole lot of dynamic dispatch happening in the Linux kernel. Between this and the other comment where you say Linus dislikes OOP I kinda get the feeling you ought to read some Linux kernel code. Because it's practically completely object-oriented and almost everything is done through a vtable for dynamic dispatch.
- noobermin 5y agoC++ has loads of inefficient abstracted programming models but rust doesn't? C++ has moved on from the days when that argument was made. This may have sufficed for an argument against C++ then but it should also apply to rust today which has similar infrastructure like generics and traits that allows a level of abstract programming that C doesn't provide.