@GlowingLantern Such absolutist view makes the problem impossible almost by definition, so it's completely impractical.

Every lock can be picked, so is there no point having doors? If a door can't be guaranteed to be really locked, why upgrade from a piece of string to a steel padlock?

@kornel your argument is the absolutist one in terms of the language. Asking how to make C++ absolutely safe in regard to object lifetime management, one arrives at rust as the answer. Except then one realizes that nothing is absolute and the language is fundamentally flawed without the unsafe code, that is there are efficient and safe data structures that are impossible to implement with the hard requirement of absolute language level safety.

C++ could easily have a subset, sticking to which you can have exact same guarantees. At that point it just becomes a question of opt-in versus opt-out. I imagine when it gets to it, we'll also know a lot more about object lifetime management, and employ better abstractions and customization points.

@GlowingLantern@misskey.de

@namark C++ has a very firm stance on backwards compatibility. It's at the point where it won't even make changes that would slightly break unofficial ABI it never promised to have.

There is unsafety identified in existing C++ constructs, and they're incompatible with what Rust found to be necessary for its safety model.

Therefore, either C++ can't have Rust's safety model, or C++ has to change its backwards-compat policy. The signs point to not having Rust's safety model.

@kornel I can only see that being true from the point of view of applying the model to absolutely everything across the board. You want raw references or pointers to be borrowing, c++ says nope of course. You want a special borrowing reference? Nothing compatibility or ABI breaking there. It's just a matter of defining good fundamental abstraction in the language standard. Yes C++ will never have rust's model, it will more likely have a few new fundamental building blocks added with which you could implement rust's model as a library, and many other similar models.

@namark "it will more likely have a few new fundamental building blocks added with which you could implement rust's model as a library"

Google literally tried to implement that:

docs.google.com/document/d/e/2

They've identified big obstacles to implementing this, including need for a different type of moves and destructors. Not as easy as new building blocks, because it touches so much of the type system and has complex semantics. They recommend adding borrowing built-in into the compiler.

@namark I recommend checking Rust's history of the borrow checker, from being scope-based (close too what could be done with a metaprogramming library), to being IR-based AKA "NLL", to Polonius project which tracks regions on control flow graph. Borrow checking is way harder than it seems. Even relatively simple code runs into issues that are either soundness holes, or become freakishly complex to prove.

Follow

@kornel took a cursory glance and it seems all backwards to me. They are trying to wedge in a borrow checker into c++ move semantics, that immediately smells to me as a dead end. It again seems to me as this weird fixation, like they have rust as a premise and try really hard to sell it. What they want is to be able write some safe code, and then unleash the spaghetti monster on it and make sure it can't introduce memory errors. What a noble goal it is.

Instead to understand what I have in mind you have to ask "can I have a library, the invariant of which, given that I don't break it on my side, is equivalent for most intents and purposes to the borrow checker". You shouldn't use std::move and try to design try to change the whole language to allow borrow checking. Whatever move function you use (be it separate or a overload of std::move) it should not get a lvalue reference and return a rvalue reference, it should deal with special types, that don't have the necessary lifetimes according to language definition, but emulate the necessary lifetimes. The immediate hurdle you run into then is lack of mutable compile type counter, by just adding that, you can already do a lot as a library. Template meta-programming a subset of prolog? Yes please!

And yes the borrow checker is way harder than rust developers thought it was, it has a lot more gray areas and tradeoffs to make, I would prefer a library of primitives that would allow me to make the all the meaningful choices there are to make.

@namark The things they're implementing aren't simply "because Rust does it". If you choose shared XOR mutable aliasing model for references, there are logical consequences of it.

I think you're severely underestimating complexity of the problem, and your approach wouldn't be sound, nor ergonomic when interacting with rest of C++.

Rust has UnsafeCell type to allow library primitives to "break" its aliasing model (this powers atomics, refcells, mutexes).

Sign in to participate in the conversation
Qoto Mastodon

QOTO: Question Others to Teach Ourselves
An inclusive, Academic Freedom, instance
All cultures welcome.
Hate speech and harassment strictly forbidden.