Remix.run Logo
johnisgood a day ago

> Also, unsafe rust is still safer than C.

I highly doubt that, and developers of Rust have confirmed here on HN that when it comes to unsafe code within a codebase, it is not just the unsafe blocks that are affected, the whole codebase is affected by that.

vsgherzi a day ago | parent | next [-]

Unsafe rust still enforces many of rust's rules. The only powers you get with unsafe rust are de-refrencing raw pointers, calling unsafe traits / functions, and the ability to access or modify mutable statics. You can read more about this here. https://doc.rust-lang.org/nomicon/what-unsafe-does.html

Unsafe rust is definitely safer than normal C. All the unsafe keyword really means is that the compiler cannot verify the behavior of the code it's up to the programmer. This is for cases where 1. the programmer knows more than the compiler 2. we're interacting with hardware or FFI.

When rust developers say unsafe effects the whole codebase what they mean is that UB in unsafe code could break guarantees about the whole program (even the safe parts). Just because something is unsafe dosen't inherently mean it's going to break everything it just needs more care when writing and reviewing just as C and C++ does.

SAI_Peregrinus a day ago | parent [-]

And an unsafe block in Rust having UB is exactly as bad as having UB in C or C++: the whole program's behavior can be altered in unexpected ways. So at its worst it's equivalent to C, but if there's no UB encountered in the unsafe block(s) then the whole program is safe, where for C you can hit UB anywhere in the program not just in annotated sections.

vsgherzi a day ago | parent [-]

It's strange to me that others push the unsafe keyword as an "I told you so". Perhaps it's just the way rust presents it. Most rustacians I follow agree that Rust's power is turning unsafe things into safe wrappers for the programmer to use. Much of the std library is implemented with unsafe to make things work at all, and this isn't really a bad thing it is heavily vetted and tested.

SAI_Peregrinus 6 hours ago | parent [-]

And I agree with those programmers! I'm one of them. They're two sides of the same coin: Rust's power is allowing the programmer to write safe wrappers around unsafe code for those cases where the compiler can't prove the code is safe, and the weakness of `unsafe` is that it allows undefined behavior to be triggered. It's effectively a consequence of Rice's theorem: there can never be a program that is capable of proving all safe programs to be safe & all unsafe programs to be unsafe. So the compiler is designed to be "conservative" and reject some safe programs when it can't prove their safety. Rust added unsafe blocks to allow programmers to manually use more powerful logic than the compiler can in order to verify the safety of their code & wrappers, but in turn had to allow UB if the programmer messes up or just outright skips that proof.

Rust's `unsafe` blocks are great, and a necessary part of the language. The reason they're great is that they allow containing the code which could exhibit UB to a subset of the program, thereby making it easier to find the source of any mistakes. But they don't (and were never intended to) provide any guarantees about what happens if UB is encountered. It's no worse than C or C++'s UB, and having it in `unsafe` blocks means it's easier to notice where it could happen, but when it does happen it's also no better than C or C++'s UB.

jcranmer a day ago | parent | prev [-]

Rust's core object semantics are very nearly that of C. Really, the only major difference between Rust and C is that you can't violate mutable aliasing rules in Rust, even in unsafe, and C has a strict aliasing mode that Rust can't opt into.

The main practical difference is that Rust pushes you away from UB whereas C tends to push you into it; signed integer overflow is default-UB in C, while Rust makes you go out of your way to get UB integer overflow. Furthermore, the general design philosophy of Rust is that you build "safe abstractions" which might require unsafe to implement, but the interface should be impossible to use in a way which doesn't cause any UB. It's definitely questionable how many people actually adhere to those rules--some people are just going to slap the unsafe keyword on things to make the code compile--but it's still a pretty far distance from C, where the language tends to make building abstractions of any kind, let alone safe ones, difficult.