4 ms·
Rust is memory safe by default, with unsafety as an optional feature that you basically never need to use unless you’re writing extremely low-level code, need a
by School-Cotton 3y ago
Rust is memory safe by default, with unsafety as an optional feature that you basically never need to use unless you’re writing extremely low-level code, need absolute maximum performance, or are interfacing with libraries written in other languages.
C++ is unsafe by default.
Of course it’s just as easy to write bugs in unsafe Rust as it is in C++ (actually, it’s probably even easier), but defaults matter.
- corethree 3y agoNo I've seen libraries that need the user to use it by default. The wgpu library is one example. It's not even that low level. Rust stuff is a little too safe that it influences code organization and modularity as well.
- jvanderbot 3y agoThis is a common conception, and I agree to a point. However, interfaces matter. At the interface to _literally any_ system call, unsafe starts to creep out. Either in the wrapper implementation, or in the interface _to_ the system, or even leaking through the wrapper to the caller. At that point, if we have to re-wrap everything in rust to hide the unsafety of the interfaces to the system (sockets, shared mem, etc etc), then why not just write safe cpp wrappers? Yes, people are writing memory overflows in their own code, but I'd argue 99% of the critical security bugs are actually in the unsafe interfaces. And we don't really need a new language to fix that. We just need new interfaces. I love Rust, but using it for anything nontrivial makes the "safe" patina really fade. You're quickly writing what feels like C, with MaybeUninit<X> all over.
- skitter 3y agoC++ makes it very difficult to write safe interfaces. You can't expose references, nor spans, nor variants, no shared_ptrs to things that can't be thread-safely overwritten, nor any standard library containers nor a lot of other things. And even if you only use whatever few interfaces remain safe, the interfaces you create are unsafe by default too. As a result, these unsafe interfaces are everywhere. I'd contend that using Rust for anything nontrivial results in MaybeUninit & co being common.
- School-Cotton 3y ago> At the interface to _literally any_ system call, unsafe starts to creep out. Either in the wrapper implementation, or in the interface _to_ the system, or even leaking through the wrapper to the caller. It’s quite rare to have to make syscalls directly in Rust, just like it is in c++. Most code in any large enough system is related to the internal logic of the system, not to its interface with the outside world. And when you _do_ need to interface with the outside world, you can use a wrapper (lots of the standard library is basically wrappers around syscalls; this is true in any language). And no, in Rust unsafety doesn’t typically “leak through” interfaces, unless those interfaces are buggy. > why not just write safe cpp wrappers? There’s no such thing. It’s not possible to write a safe interface to c++ code in the sense that that term is used by the Rust community. In Rust, “safe interface” means: assuming there are no bugs in the underlying code, and the client code never invokes `unsafe`, using the interface cannot cause undefined behavior. This is impossible to guarantee in c++. > I love Rust, but using it for anything nontrivial makes the "safe" patina really fade. You're quickly writing what feels like C, with MaybeUninit<X> all over. This is not true at all in my experience. I work on Materialize, surely one of the more non-trivial Rust programs that exists. We use very little unsafe/MaybeUninit/C-like code. Do you have an example of a codebase you’re thinking of that does this?
- jvanderbot 3y agoOK this is reasonable. Perhaps my experience skews towards the lower-level a bit too much. And it's also reasonable I'm misusing the language given it's not my day job. To answer your question, I'm referring to much of the networking code in socket2 / socket, which uses MaybeUninit when doing non-standard stuff like forming your own packets. (RAW)
- School-Cotton 3y agoYep, I definitely buy that if you're doing very low-level stuff, C or C++ might be more ergonomic than Rust. But I don't think that covers most of the real-world use of C++. I'm not too familiar with `socket2` but normally in Rust to construct a buffer with arbitrary bytes in safe code you would first zero it out and then write it. Using `MaybeUninit` there is presumably just a micro-optimization to avoid having to memset things to zero.
- Measter 3y agoI feel I have to disagree with your (implied) contention that it's feasible to write an API in C++ that, no matter what its inputs are, cannot ever exhibit undefined behaviour. Because that's what "safe" in Rust means. No memory safety errors, no undefined behaviour.
- hulitu 3y agoWho operates crates.io ?
- School-Cotton 3y agoIt’s owned by the Rust Foundation.