most of this seems to be an issue of maturity for the language itself and the surrounding ecosystem, which I did touch on a little bit. I probably should have made it a more explicit caveat.
aside from ubiquity and maturity, I'm curious what features c has that rust lacks for raw memory manipulation. I have yet to work my way through all of the rustonomicon and I am far from an expert c programmer, so I would appreciate the opportunity to fill in some knowledge gaps.
I agree that for C it’s mostly the ecosystem i.e. external tools & libraries. There’re just a few features in the language and runtime, such as debug heap and the preprocessor.
But C++ has a lot to offer besides tooling. Modern-style C++ (template containers, smart pointers) solve the majority of safety issues solved by safe Rust. But C++ doesn’t hide these raw pointers behind safe abstractions, and that higher level safer stuff is optional.
For specific features helping with raw memory manipulation see e.g. routines from <algorithm> header, http://en.cppreference.com/w/cpp/algorithm They are part of C++ standard library, and yet they support dangerous C arrays, because raw C pointers double as C++ iterators.
I’d characterize the situation differently; Rust handles a lot of things that Modern C++, and not even the Core Guidelines, try to handle. Iteration invalidation is huge. Concurrency and parallelism issues are huge.
I very much welcome these things, as I’m about safe software, not “only Rust”, but I don’t think the “most” claim holds water.
If you prioritize performance over safety, there’s no way around these problems. To implement efficient algorithms processing trees, lists or graphs, you have to fallback to unsafe code & potentially invalid raw pointers. Unsafe Rust is as dangerous as C++, but for C++, standard library, runtime and tools provide huge help implementing and debugging such things.
If you prioritize safety over performance, of course Rust is way ahead of C++. But Java and C# are much easier to use and deliver safety comparable to Rust. Also in these languages, trees & graphs might be even faster than in safe Rust.
We believe this is a false dichotomy. If Rust is significantly slower than C++, it’s a bug. Generally, most of the time, we have succeeded at this, sometimes being faster, sometimes slower.
Most of those tools work on Rust as well. And we are pretty sure we can have better tools in the future, but that’s a while off.
> If Rust is significantly slower than C++, it’s a bug.
Safe Rust is significantly slower than C++ when working with pointer based stuff like trees and graphs. That’s why people use unsafe Rust for that kind of code.
> Most of those tools work on Rust as well.
It’s not just tools, also language and libraries.
Rust was designed for safety, and apparently unsafe was just neglected. Or maybe it was a decision to neglect making people use safe Rust instead (BTW same decision was made by Java’s designers at Sun).
In any case, the current state of unsafe Rust is not OK. AFAIK, stable unsafe Rust doesn’t even has malloc & free functions.
Yes. Unsafe code must exist for Rust to accomplish it's goals. Rust is also a practical language, and unsafe is an important part of that. The key is, unsafe is a relatively small percentage of code overall; even operating system projects have a very small amount of unsafe.
> apparently unsafe was just neglected.
I wouldn't agree with this. We work on unsafe things all the time; for example, NonNull<T> was just stabilized. As with any open source project, stuff gets done as people have the time and desire to do it.
> AFAIK, stable unsafe Rust doesn’t even has malloc & free functions.
So, this is literally true, but it's not because we hate unsafe or something. It's because a good allocator API is hard. We've been putting a lot of work into it over the last year or so, and it's actually pretty close to being in stable. The team moved to stabilize it back in October of last year, but some last-minute stuff has popped up.
> unsafe is a relatively small percentage of code overall
I don’t think it’s a good idea to talk about percentage of code overall when discussing Rust. Take a look at http://githut.info/ you’ll see that majority of overall code is higher-level GC languages.
I’ve been professionally developing software since 2000, have a lot of experience with different languages and platforms, and I’m speaking from my experience. There’re 2 major reasons why now in 2018 I still pick C++ for some software or some components of it.
(1) Code that relies heavily on native interop. Like OS APIs for lower-level device IO, advanced networking stuff, GPU interop, other OS APIs. All of these APIs are C, or sometimes on Windows it’s C++.
(2) Performance-critical CPU bound code. One part of that is SIMD, but pointer-based structures also help a lot, and they are not small percentage of my code. BTW, another thing missing in current Rust is custom allocators. In C++ I can implement a custom allocator in just a couple hundred lines of code, and plug it into any collection for non-trivial performance gain in some use cases: https://github.com/Const-me/CollectionMicrobench Another C++ feature helping me with these performance-critical calculations is OpenMP.
Of course, Rust evolves quite fast, and it may change some day. But in its current state, I don’t think Rust is an adequate C++ replacement for the kind of problems I solve in C++.
aside from ubiquity and maturity, I'm curious what features c has that rust lacks for raw memory manipulation. I have yet to work my way through all of the rustonomicon and I am far from an expert c programmer, so I would appreciate the opportunity to fill in some knowledge gaps.