Live data from Hacker News

Rusty.hpp: A Borrow Checker and Memory Ownership System for C++20

github.com

91–100 of 174 posts

Re: Rusty.hpp: A Borrow Checker and Memory Ownership System for C++20

#91

Earlier quoted context omitted.

> Most of the time, I want to pass/return a reference Surprised to hear that you want to return a reference so frequently.

How else would you implement C++’s vector::operator[] for example? This to me is the clearest example of something that’s safe in Rust, and impossible to make safe in C++.

> How else would you implement C++’s vector::operator[] for example?

Are you asking in a theoretical world where it isn’t defined to already return a `T&`?

Re: Rusty.hpp: A Borrow Checker and Memory Ownership System for C++20

#92
post #69

Earlier quoted context omitted.

> Most of the time, I want to pass/return a reference Surprised to hear that you want to return a reference so frequently.

It's not really my choice, I'm working in a big codebase I didn't write. Lots of large classes containing large collections with getters and setters.

Ah, that’s unfortunate.

Re: Rusty.hpp: A Borrow Checker and Memory Ownership System for C++20

#94
One huge caution about this - this uses RefCell*-like semantics which means that the borrow/borrow_mut checking is not thread-safe. This is dangerous because in the docs they have examples of shared_ptr in there but using that from multiple threads would be UB - there's 0 cases where this + shared_ptr makes sense unless you transparently upgraded to an atomics-based variant. Similarly, in a thread-aware implementation you'd expect more efficient handling of locks as well (i.e. borrow / borrow_mut would just acquire a lock and return a proxy without any additional borrow checks).

The other footgun is that there's no concept of a non-owning pointer which is dangerous - there are several equally dominant conventions in C++: naked pointers might be heap allocated, it might represent an optional const&, or it might be a pointer to the stack. Ingesting naked pointers should probably require an explicit annotation instead of assuming it's a new'ed pointer.

It's a neat idea, but I suspect this particular implementation is likely to introduce more UB, not less, because of the thread-safety footguns. In a single-threaded system, the borrow checker doesn't add a huge amount. The biggest gain is of lifetime enforcement which this doesn't get you. Also because you have to construct these Vals at point of initialization of your value, it's viral. Upgrading input arguments to use this can be dangerous if dealing with pointers.

* For C++ users, RefCell is a compile-time borrow checker escape hatch to do the checking at runtime instead - you can borrow immutably as many times xor borrow once mutably - anything else is a abort.

Re: Rusty.hpp: A Borrow Checker and Memory Ownership System for C++20

#95
post #51

Earlier quoted context omitted.

> pretty complicated(possibly impossible) Rust does it at compile time, so why cant C++? to me this detail completely kills the usefulness of this project

C++ cannot because it does not have the necessary information present in its syntax. It’s really that simple. C++ could add such syntax, but outside of what Circle is doing, I’m not aware of any real proposal to add it. Also, Google (more specifically, the Chrome folks) tried to make it work via templates, but found that it was not possible. There’s a limit to template magic, even.

I'm pretty sure you could embed a language with lifetimes in a dsl built with c++ templates. You wouldn't want to use it beyond toy programs though.

Re: Rusty.hpp: A Borrow Checker and Memory Ownership System for C++20

#96

Earlier quoted context omitted.

How else would you implement C++’s vector::operator[] for example? This to me is the clearest example of something that’s safe in Rust, and impossible to make safe in C++.

> How else would you implement C++’s vector::operator[] for example? Are you asking in a theoretical world where it isn’t defined to already return a `T&`?

Now that GP said it, it'd be nice to be able to write "some_map[i].value_or(some_value)".

Re: Rusty.hpp: A Borrow Checker and Memory Ownership System for C++20

#97

Can someone familiar with both please explain the benefit of Rust's borrow checker memory management model over C++'s std::unique_ptr and shared_ptr ? Is there some safety argument to prefer Rust's model, or is it something else ? I'm not aware of any C++ compiler doing it, but it seems smart pointer overhead could be automatically and safely reduced (in same way one can do it manually) by the compiler lowering the g…

Rust has unique and shared pointers too (Box and Arc/Rc). But using them when unnecessary results in extra heap allocations. I’m not aware of C++ compiler that can consistently rewrite uses of unique_ptr to heap-allocated objects to use raw pointers to stack-allocated objects instead.

I didn't mean trying to rewrite code to change dynamically allocated objects to stack based ones. That sounds more like an optimization that a managed language like C# might do.

C++'s unique_ptr and shared_ptr both have a get() method that will return you a raw pointer to the managed object, which can be a safe optimization within a function holding ownership to the object, as well as allowing you to use legacy functions on it that take raw pointer arguments.

I was thinking the C++ compiler could itself realize when it is safe to do so, save the raw pointer to a temp variable, and "rewrite" smart pointer accesses to use this temporary raw pointer. One could even imagine the compiler changing smart pointer function parameters to raw pointers in some circumstances.

Re: Rusty.hpp: A Borrow Checker and Memory Ownership System for C++20

#98
post #77

Earlier quoted context omitted.

C++ cannot because it does not have the necessary information present in its syntax. It’s really that simple. C++ could add such syntax, but outside of what Circle is doing, I’m not aware of any real proposal to add it. Also, Google (more specifically, the Chrome folks) tried to make it work via templates, but found that it was not possible. There’s a limit to template magic, even.

Although it's not as extensive as Rust's lifetime management, Nim manages to infer lifetimes without specific syntax, so is it really a syntax issue? As you say, though, C++ template magic definitely has its limits.

Nim has a garbage collector.

That said, you're right on some level that it's truly semantics that matter, not syntax, but you need syntax to control the semantics.

Re: Rusty.hpp: A Borrow Checker and Memory Ownership System for C++20

#99

Earlier quoted context omitted.

C++ cannot because it does not have the necessary information present in its syntax. It’s really that simple. C++ could add such syntax, but outside of what Circle is doing, I’m not aware of any real proposal to add it. Also, Google (more specifically, the Chrome folks) tried to make it work via templates, but found that it was not possible. There’s a limit to template magic, even.

I'm pretty sure you could embed a language with lifetimes in a dsl built with c++ templates. You wouldn't want to use it beyond toy programs though.

[deleted]

Re: Rusty.hpp: A Borrow Checker and Memory Ownership System for C++20

#100

Earlier quoted context omitted.

How else would you implement C++’s vector::operator[] for example? This to me is the clearest example of something that’s safe in Rust, and impossible to make safe in C++.

> How else would you implement C++’s vector::operator[] for example? Are you asking in a theoretical world where it isn’t defined to already return a `T&`?

No, that’s my point. It returns a reference. So it’s a good example of when you might want to return a reference, which you said seemed uncommon. But the reference it returns is unsafe (for example, it gets invalidated if the vector is later resized), whereas the reference returned by the corresponding Rust operator is safe.
Post reply on HN