Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Here's another perspective on why things are the way they are:

One of the central philosophies of Rust is that it should not be possible to execute undefined behavior using only safe code. Rust's underlying core semantics end up being very similar to C's semantics, at least in terms of where undefined behavior can arise, and we can imagine Rust's references as being wrappers around the underlying pointer type that have extra requirements to ensure that they can be safely dereferenced in safe code without ever causing UB.

So consider a simple pointer dereference in C (*p)... how could that cause UB? Well, the obvious ones are that the pointer could be out-of-bounds or pointing to an expired memory location. So references (& and &mut) most point to a live memory location, even in unsafe code. Also pretty obviously, the pointer would be UB were it unaligned, so a Rust reference must be properly aligned.

Another one that should be familiar from the C context is that the memory location must be initialized. So the & reference in Rust means that the memory location must also be initialized... and since &mut implies &, so must &mut. This part is probably genuinely surprising, since it's a rule that doesn't apply to C.

The most surprising rule that applies here as well is that the memory location cannot be a trap representation (to use C's terminology). Yes--C has the same requirement here, but most people probably don't come across a platform that has trap representations in C. The reason why std::mem::uninitialized was deprecated in favor of MaybeUninit was that Rust has a type all of whose representations are trap representation (that's the ! type).

In short, the author is discovering two related issues here. First, the design of Rust is to push all of the burden of undefined behavior into unsafe code blocks, and the downside of that is that most programmers probably aren't sufficiently cognizant of UB rules to do that rule. Rust also pushes the UB of pointers to reference construction, whereas C makes most of its UB happen only on pointer dereference (constructing unaligned pointers being the exception).

The second issue is that Rust's syntax is geared to making safe Rust ergonomic, not unsafe Rust. This means that using the "usual" syntax rules in unsafe Rust blocks is more often than not UB, even when you're trying to avoid the inherent UB construction patterns. Struct projection (given a pointer/reference to a struct, get a pointer/reference to a field) is especially implicated here.

These combine when you deal with uninitialized memory references. This is a reasonably common pattern, but designing an always-safe abstraction for uninitialized memory is challenging. And Rust did screw this up, and the stability guidelines means the bad implementations are baked in for good (see, e.g., std::io::Read).



If Rust's syntax is geared to making safe Rust ergonomic, they should start by not requiring method calls to read or write from a &Cell<T> (because in C++ you don't need method calls to read or write from a T&).


Needing to use a `Cell` in rust is incredibly rare in my experience. It's very far from clear to me that the increased complexity coming from allowing overriding the meaning of `=`, and worse of `variable_name_that_happens_to_contain_a_certain_type` would be remotely worth it.


Unless GUI code comes up with Rc<RefCell<>> all over the place.


RefCell is distinct from Cell, more common, but much worse tradeoffs for implicit access, because accessing it can crash your program.


I want Cell to be more ergonomic because it addresses the same Rust weak points as RefCell but without runtime overhead and panicking. I think RefCell<struct> should be an infrequently used type that you reach for when you specifically want to guard against reentrancy, and struct{Cell} should be the primary replacement for shared access in other languages. The latter is sound but introduces a lot of boilerplate syntax.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: