4 ms·
It's not, but it's very good for writing system software. Modern C++ is also good, probably good enough for the majority of the cases, but Rust is there for you
by orthoxerox 4y ago
It's not, but it's very good for writing system software. Modern C++ is also good, probably good enough for the majority of the cases, but Rust is there for you when you can't afford a GC and you must be absolutely right you're not introducing memory management errors.
- HarHarVeryFunny 4y agoIf you're using modern C++ then you really have to be screwing up to introduce memory management errors. For 99% of programs high level (STL-based) types are sufficient, and if you really need to be allocating things yourself, then smart pointers and RAII make it pretty hard to mess up, unless you choose to circumvent the scope-based lifetime they provide and start doing things like ptr.release() instead. To me C++ pretty well follows the "make simple things easy/safe, and hard things possible" philosophy. I'm glad this it still does support low level stuff, but the use cases for that are minimal and I do wish there was a compiler flag to reject full C backwards compatibility and only support a modern safe subset, so that projects could protect themselves from junior developers shooting themself in the foot.
- dthul 4y agoSmart pointers and other managed types are nice, but memory errors are still easy to make, e.g. pushing into a std::vector from several threads.
- HarHarVeryFunny 4y agoWell, yeah, but that's not really a memory error - it's an error of not using mt-safe data structures for mt programming. It's no different than using int vs std::atomic<int> in an mt context. It's a shame that C++ doesn't provide mt-safe versions of STL types in the standard library, although trivial to wrap them yourself (1 line of code per method, using std::lock_guard). Are all Rust data types mt-safe? Does unsafe mode provide faster unprotected versions if you need those?
- steveklabnik 4y ago> Are all Rust data types mt-safe? Yes, but not in the sense you probably think, given your second sentence: > Does unsafe mode provide faster unprotected versions if you need those? Some data types can be safely shared between threads, and some cannot. Rust checks at compile time if you try and use a non-thread safe data structure from multiple threads, and if you do, will give you an error. So in that sense, all of them are safe, yes. You don’t use unsafe to get access to non-thread safe data structures, you may have both kinds, and the compiler checks you use them correctly.
- HarHarVeryFunny 4y agoInteresting. So I assume there are at least both basic and thread-safe versions of basic types like string/list/vector/map ? Is there any provision for building your own thread-safe types (e.g. a structure composed of other types) out of non-thread-safe types and mutexes, and if so how does that work in terms of compile-time errors ?
- davidatbu 4y ago> I assume there are at least both basic and thread-safe versions of basic types like string/list/vector/map ? To my knowledge, no. If you want to push to a vector from multiple threads, you "wrap" the vector in a `Mutex`. The difference between C++'s std::mutex or std::lock_guard and Rust's Mutex, is that the compiler refuses to let you touch the data protected by the mutex unless you have a lock acquired on the mutex. > Is there any provision ... Yes! 1. In Rust, types can implement "traits". 2. There's two traits that control thread safety: `Send`, and `Sync` Basically, any type that "implements the trait" `Send` is safe to send across threads. And a reference of any type that implements `Sync` is safe to to send across threads. 3. `Send` and `Sync` are "auto-traits", which means that if you make a data structure out of primitives that all implement `Send`, your data structure will also implement `Send`, same for `Sync`. 4. There are a bunch of thread-safety primitives that you can use (like `Arc` (atomic reference counters), `Mutex`, ..etc) to build thread safe data structures. > how does that work in terms of compile-time errors? The compiler will not let send a type across threads if it doesn't implement `Send`, and it won't let you send a reference to a type if the type doesn't implement `Sync`! That way, if you avoid using the `unsafe` keyword, and the compiler agrees to compile your code, you can be sure you won't have data races!