Earlier quoted context omitted.
missing data structure helper -- didn't you already just name-check that though, since that's basically RefCell .. or if you're willing to roll the dice... UnsafeCell (aka "trust me I know what I'm doing")?
What you essentially want for the user to not write any unsafe code is this kind of interface: trait Allocator { fn allocate (&'a self, init: T) -> Handle ; fn deallocate (&'a self, handle: Handle ); fn read (&self, handle: Handle ) -> impl Deref ; fn write (&self, handle: Handle ) -> impl DerefMut ; } &'a RefCell is pretty close to a definition of Handle , except that Rust provides no implementations of allocate and…
Making C++ safe without borrow checking, reference counting, or tracing GC
141–150 of 226 posts
Re: Making C++ safe without borrow checking, reference counting, or tracing GC
#142Earlier quoted context omitted.
> Slotmap uses unsafe everywhere, it's a memory usage pattern not supported by the borrow checker. Is disabling the borrow checker really a common pattern in Rust? Wrapping "unsafe" code in a safe interface is a common pattern in Rust, yes. There is absolutely nothing wrong with using "unsafe" so long as you are diligent about checking invariants, and keep it contained as much as possible. Obviously the standard libr…
If unsafe means “safe but the compiler cannot verify” then I guess just consider .cpp to mean “safe but the compiler cannot verify” and we have suddenly made C++ memory safe
Re: Making C++ safe without borrow checking, reference counting, or tracing GC
#143Earlier quoted context omitted.
I really love parts of rust and kinda hate other parts. but this is what really ruins it for me. I want to play. I want to knock something together and work with it and see what kind of shape it is. rust demands that I cross every last t before I can run it at all. which is great if you already have a crystal notion of what you are building
> rust demands that I cross every last t before I can run it at all. It's worse than that IMO. Rust makes it very awkward/impractical to have cyclic data structures, which are necessary to write a lot of useful programs. The Rust fans will quickly jump in and tell you that if you need cycles, your program is wrong and you're just not a good enough programmer, but Maybe it's just that the Rust borrow checker is too li…
I have absolutely never heard a Rust fan say this. AFAICT the fact that cyclic data structures are hard to write is widely accepted within the community as one of the negative tradeoffs of the language.
If you’re talking to people who claim that any language is better than all others in every possible way, for every possible use case, then they are zealots whose opinion can be ignored.
Re: Making C++ safe without borrow checking, reference counting, or tracing GC
#144The reason I use Rust is because I can bypass all this messy business altogether and have my sensible patterns wrapped in a usable syntax and enforced by the compiler out of the box. Whenever people say "just follow these rules" I read "just add this extra mental burden and do not slip up". Computers were invented to automate things. Rust automates ownership and borrowing rules. Suggestions like "do not forget to ini…
So how do we serve those users? Rust doesn’t give them a path forward. Simply getting C++ compilers to agree is difficult enough, much less an entirely different language.
Re: Making C++ safe without borrow checking, reference counting, or tracing GC
#145There is also Type-After-Type: https://dl.acm.org/doi/10.1145/3274694.3274705 (though maybe that's covered by what the author meant by "arenas").
I wrote a bit about using type-after-type as the basis for an entire language (Arrrlang, with a parrot mascot) in my last article [0] and a little bit in a post about memory safety for unsafe languages [1] which we eventually talked about at Handmade Seattle.
The downside is the extra memory usage, but I think we can combine it with temporary regions [2] to reduce it pretty drastically.
TIL the phrase type-after-type! I've also heard it referred to as type stability. [3] [4] If you squint, this is what we often do manually with Rust when the borrow checker influences us to use indices/IDs into central collections.
[0] https://verdagon.dev/blog/myth-zero-overhead-memory-safety
[1] https://verdagon.dev/blog/when-to-use-memory-safe-part-1#the...
[2] https://verdagon.dev/blog/zero-cost-borrowing-regions-overvi...
[3] https://www.usenix.org/legacy/publications/library/proceedin...
[4] https://engineering.backtrace.io/2021-08-04-slitter-a-slab-a...
Re: Making C++ safe without borrow checking, reference counting, or tracing GC
#146it's not about making C++ memory safe, but about describing a safe subset of C++
Edit: Actually nevermind! CHERI is a hardware technique that can make C++ memory safe without using only a subset of the language.
Re: Making C++ safe without borrow checking, reference counting, or tracing GC
#147Earlier quoted context omitted.
What you essentially want for the user to not write any unsafe code is this kind of interface: trait Allocator { fn allocate (&'a self, init: T) -> Handle ; fn deallocate (&'a self, handle: Handle ); fn read (&self, handle: Handle ) -> impl Deref ; fn write (&self, handle: Handle ) -> impl DerefMut ; } &'a RefCell is pretty close to a definition of Handle , except that Rust provides no implementations of allocate and…
Can you clone a Handle? If so, how do you handle using a clone after freeing it? If clones are refcounted, how do you handle cycles?
Effectively, handles are like weak pointers in that you can detect when the underlying object has been freed, but unlike weak pointers, there's no need for a reference counter to know when to deallocate the object--the object is freed when the allocator itself dies, or it can manually be freed earlier. It is possible to write code that will attempt to use the freed object, and the compiler will be happy, but the runtime will detect that it has been freed and panic instead. (RefCell does something similar, except it only detects violations of multiple readers xor one writer requirement, not overall lifteime). You can also add other wrappers around Handles to automatically free those Handles on scope exit, but the point is you can now have multiple references to an object that can be upgraded to a mutable reference if you desire.
Re: Making C++ safe without borrow checking, reference counting, or tracing GC
#148Earlier quoted context omitted.
What you essentially want for the user to not write any unsafe code is this kind of interface: trait Allocator { fn allocate (&'a self, init: T) -> Handle ; fn deallocate (&'a self, handle: Handle ); fn read (&self, handle: Handle ) -> impl Deref ; fn write (&self, handle: Handle ) -> impl DerefMut ; } &'a RefCell is pretty close to a definition of Handle , except that Rust provides no implementations of allocate and…
Did you get a look at https://github.com/rust-lang/rfcs/pull/3446 at all?
Re: Making C++ safe without borrow checking, reference counting, or tracing GC
#149The reason why safety in C++ is difficult to achieve is due to the memory model used by C and C++. The memory model is a flat space provided by the OS that can be addressed by pointers. In this sense, C++ is similar to assembly code. A language like Java, on the other hand, assumes a different model where you can only access objects with well defined behavior. To change this, one needs to disallow the use of native p…
That's pretty much what the article says though. "Don't use traditional pointers" is a fairly trivial rule to enforce via static analysis, and constructs like unique_ptr are syntactically identical anyway. The bit that has me confused is that it's inventing a new term, "borrowing affine style", to describe a longstanding paradigm that has traditionally been called "RAII". Now, neither term is very clear, but surely i…
(Also, I used the term "borrowless affine style" mostly because people might hear the term "affine style" and assume I'm talking about Rust, since that's what most people know.)
Re: Making C++ safe without borrow checking, reference counting, or tracing GC
#150The reason I use Rust is because I can bypass all this messy business altogether and have my sensible patterns wrapped in a usable syntax and enforced by the compiler out of the box. Whenever people say "just follow these rules" I read "just add this extra mental burden and do not slip up". Computers were invented to automate things. Rust automates ownership and borrowing rules. Suggestions like "do not forget to ini…