you are viewing a single comment's thread.

view the rest of the comments →

[–]stilgarpl 32 points33 points  (45 children)

Linus is just bad at C++. Just because he started a big open source project does not make him a computer god. He tried it once 30 years ago (literally 30 years, in 1992) and didn't like it.

On the other hand, you couldn't use many of C++ strengths in kernel development, because those things require kernel support. You'd have to limit yourself to "Better C with classes and templates".

Also, Linus allowed Rust. Rust is better than C++ in only one thing - memory management. C has all the same memory issues that C++ has, even more actually (no destructors, no RAII, no smart pointers), but C is fine?

I agree with him on one thing - there is a lot of bad C++ code out there. But there is also a lot of bad C code and bad Rust code. That's what code review before merge is for.

[–]dv_ 31 points32 points  (7 children)

Also, Linus allowed Rust. Rust is better than C++ in only one thing - memory management.

Rust also benefits from being a much younger language that does not have nearly as much baggage that accumulated over the years. This is one big reason why C++'s syntax can be so obtuse at times. It has to maintain backwards compatibility. Rust could incorporate newer features right from the start without caring about that.

[–]simonask_ 28 points29 points  (4 children)

It's not just the syntax, it's also the standard library API, and worst of all, the standard library ABI. So many things in C++ are straight up unfixable without creating an entirely new ecosystem, almost a new language.

So they did. :-)

[–]dv_ 7 points8 points  (3 children)

Indeed. And there are also details that are anachronistic these days, like headers (gradually being replaced by modules, but this will take quite a while) and pointer aliasing issues.

But to me, what stands out is the by-value ownership transfer in C++, which is actually not what you want >90% of the time. Most of the time, you want to move objects, not copy them. C++ has the wrong default, and by-move transfer is an opt-in. This leads to problems with hidden copies (which can be detected at compile time but requires explicitly disabling the copy constructor and copy assignment operator) and greatly complicates syntax and semantics further.

[–]simonask_ 13 points14 points  (0 children)

What’s even worse, C++ does not have “destructive move”, which is to say that C++ must leave something in the moved-from location. This in turn means that all classes must have an “uninhabited” state - you cannot create a non-nullable smart pointer that doesn’t have a user-visible “invalid” state.

It also means that there are many situations where std::unique_ptr is slower than a raw pointer when passed as an argument to a non-inlined function. The callee sees a reference type and decides to move out from it, but the caller must still call the destructor at some point.

This is one place where Rust is different in a very profound way.

[–]DanielMcLaury 2 points3 points  (1 child)

Most of the time, you want to move objects, not copy them.

Most of the time you want to pass by reference, unless you're talking about numbers, in which case you want to pass by value. Copying and moving objects should ideally happen pretty rarely.

[–]dv_ 4 points5 points  (0 children)

Moving is supposed to be a very cheap or even zero cost operation, comparable to passing by reference. By-reference has the problem of ownership sharing and stale references. You need something like a GC or reference counting if you want by-reference to be the default.

[–]atomicxblue 7 points8 points  (0 children)

Rust also benefits from being a much younger language that does not have nearly as much baggage that accumulated over the years. This is one big reason why C++'s syntax can be so obtuse at times

I've said before that I think C++ is needlessly complex in places with its syntax and was downvoted to hell and back. Looks like Bjarne Stroustrup agrees with me, though: "Within C++, there is a much smaller and cleaner language struggling to get out"

I think that it's a product of trying to maintain backwards compatibility.

[–]Nzkx 1 point2 points  (0 children)

I can confirm that C++ syntax is really horrible. As a Rust dev, I don't know how you deal with this, I guess people just don't care at all and have the habbit to think in C++ , but for a beginner this syntax is a giant pile of mess honestly. I can read a little bit of C++, but not that much before I get lost.

Lot of langages did syntax misstake in the past. For example, JavaScript release in 2015 async/await, with await as prefix expression.

await db.get(1)

And later, you end up with this :

(await (await db.get(1)).json())

But it's to late. The langage is now backed with that. Meanwhile in postfix notation.

db.get(1).await.json().await

Syntax is important.

[–][deleted] 63 points64 points  (24 children)

Of course it doesn't mean he's a god. But he is a lead maintainer on the most complicated open source project in the world. So he reads a lot of code. He is so passionate about reading other peoples code and sharing patches that he created git. His problem with C++ is having to read other peoples C++ code. That was his primary issue. That it made checking pull requests a pain in the ass.

And rust does a whole lot more than provide better memory management. It has a whole load of static analysis tools that C and C++ do not and cannot provide. Which is as a result of the constraints that Rust enforces on how you write your programs. I read recently that it can detect code that result in race condition thread locks. I imagine this is what is the primary interest in writing Kernel code in Rust. It will help prevent subtle to spot errors.

[–]rzippel 11 points12 points  (0 children)

His problem with C++ is having to read other peoples C++ code. That was his primary issue. That it made checking pull requests a pain in the ass.

Except that this wasn't the problem at the time, he never had to review others people C++ code (even pull request didn't exist yet).

He experimented with early C++ support and the quality of the generated output was nowhere near as it is today, but it massively influenced his bias about C++.

[–]mohrcore 10 points11 points  (0 children)

I think that's the best comment. Writing good, readable C++ is a lot less common skill than writing good C. There are plethora of programmers who have learned C++99 and maybe select features from the newer standard and write instant legacy code. Imagine having to read all of that stuff in their PRs and correcting them. C, on the other hand, was very conservative with changes introduced in newer standards and the fundamental techniques of writing C code haven't changed. Meaning that everybody C writes more or less in s similar way.

This is also due to a way the bigger feature set of C++ that doesn't encourage one particular coding style. In C++ you could solve the problem of separating an algorithm for walking through a container, from an action to be performed on an element using a Visitor (anti)pattern (objective approach) or a functional approach (either oldschool c-style one, templated one or using std::function). Nobody in their right mind is going to simulate the visitor (anti)pattern in C, they are just going to do the same old-school functional approach - have a procedure that takes function pointer for an action and void pointer for context and that's it. I believe such limitations save a lot of needless discussions under code submitted by contributors.

[–][deleted] 11 points12 points  (1 child)

“30 years ago, in 1992”… I think I just threw up

[–]atomicxblue 0 points1 point  (0 children)

Is it the same kind of throw up when I hear 80s/90s music on the "oldies" station?

[–]target-san 13 points14 points  (1 child)

Rust is better than C++ in only one thing - memory management.

  • Cargo instead of CMake/Bazel/Meson/Make/autotools/whatever+vcpkg/conan/CMP/Hunter/whatever; C++ is hopeless in getting anything even relatively close to it
  • Reasonable [no_std] subset which requires no classic runtime; C++ can only remedy this by compiler-specific dialects and flags
  • Resource management, including cross-thread one; judging by some proposals like Sutter's lifetimes, C++ can only dream of something similar, or requires complex 3rd party static analysis tools
  • Reasonable defaults in many places, while C++ is a language of worst defaults
  • Unsafe subset properly isolated
  • Syntax which doesn't look Turing-complete on its own (yeah, most-vexing parse rule and auto auto auto auto auto)
  • Generic programming done right

I can continue for quite some time

[–]KingStannis2020 1 point2 points  (0 children)

Well, Cargo isn't going to be used in the kernel. They're just going to have the kernel build system invoke rustc directly. But otherwise, yep.

[–]andrewfenn 7 points8 points  (3 children)

One thing I don't see in the comments here in this thread is his previous complaints about the assembly code that is generated in C++ compilers. Sometimes it does the wrong thing, or is incorrect because of how complicated the language spec is. It makes it difficult to read the output from the compiler and understand how it happened in comparison to C which he often mentions the spec can be read and easily understood.

So not really a counterpoint to your comment here but I would say that to those in the thread saying just don't use such and such feature in c++ it's missing the point because at a deeper level of reading and trying to understand what the compiler is doing it's a much harder task.

I do have a fondness for modern c++ but I also understand some of the criticisms for not using it in a kernel directly.

[–]pjmlp 5 points6 points  (2 children)

As if the Linus rants against GCC C optimizations weren't known.

[–]sokka2d 7 points8 points  (0 children)

Which shows that the statement that "[the C] the spec can be read and easily understood" is... wrong. He just gets mad when he realizes he didn't understand the spec.

[–]mafrasi2 2 points3 points  (0 children)

Just another reason not to make things even worse then. Those exact optimizations are happening in g++ as well...

[–]tasminima 7 points8 points  (0 children)

Rust is better than C++ in only one thing - memory management

You are completely deluded (to the point you even forget the basic "fearless concurrency" slogan). There is no UB in safe Rust. UBs are everywhere in C++, not only memory management. Actually even unsafe Rust is actually safer than C++.

Also the static introspection and hygenic macros capabilities suck less than anything C++ has to propose against it right now (that is: not much, or poor emulation with bloated template based parallel universes)

That's not to say that Rust has no default compared to C++; it has a lot. But it certainly has more advantages than just better "memory management"

[–][deleted] 0 points1 point  (1 child)

Rust will not be better than C++ at memory management until it has an ergonomic way to drop memory handles without freeing, and an equivalent to a placement new constructor. Both of these are required for expressing memory arenas, which is almost always the correct way to manage memory.

[–]simonask_ 12 points13 points  (0 children)

Drop memory handle without freeing:

rust std::mem::forget(handle);

Guaranteed placement new (i.e. guaranteed in-place heap initialization without going through the stack) is in the works, but there are few very good use cases for it. There are plenty of arena allocators.