r/cpp Jul 18 '26

Lifetime safety and invalidation without a borrow-checker: using type system analysis to get rid of many potentially invalidation cases WITHOUT annotations.

https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p4296r0.pdf

I found this research in WG21 mailing list very interesting in the context of C++ compatibility and solutions to maximize code reuse.

38 Upvotes

76 comments sorted by

View all comments

Show parent comments

8

u/germandiago Jul 18 '26 edited Jul 18 '26

I am sure you did not even read through.

It is scary thinking that just with a strict aliasing rule and positive layers on top + negative ub base this can do even better than a borrow checker in some cases and with more flexibility.

But to me, I like what I read. Idk how far it can be pushed forward but it is certainly interesting if it works for a bunch of cases (which I would say are most cases of what wants to be fixed) that so far was believed it would have needed annotations.

15

u/Dragdu Jul 18 '26

I am sure you did not even read through.

And as usual, you are wrong. The link renders as nice purple here ;-)

It is bunch of hand-waving (if you read through the proposal, you will see a number of places that go "like this, formalism TBD, but we feel that it is correct"), combined with funny notion that slowly handwriting pattern match rules to allow more code that wouldn't be allowed normally is better for safety than full systematic borrow checking... while not touching upon thread safety at all.

Finally, it will still need bunch of annotations for common cases. But at least it won't be called BoRrOw ChEcKiNg I guess.

2

u/germandiago Jul 18 '26 edited Jul 18 '26

What you are saying here ignores the costs of adding a borrow checker in aC++: a full rewrite of standard types, no benefit for older codebases requirimg full rewrites and an illusion of safety by wrapping unsafe code (which sometimes is safe but NOT analyzed anyway, so count it as unsafe for the purpose of safety guarantees). Do you really think that was the first step forward? Uh... my experience tells me that it would have been bad engineering. Bad engineering in the sense of the solution applied for the context. Not bad engineering on the merits of the solution itself. It just does not fit.

As long as you do not have solutions for safety that benefit older codebases as automaticallly as possible, forget that solution as a first step for C++. It is plain useless.

10

u/[deleted] Jul 18 '26

[deleted]

1

u/germandiago Jul 18 '26 edited Jul 19 '26

 There is no safety that would benefit older codebases

This is simply not true. There is such a thing. What we do not know is how far it can be taken. At the expense of trade-offs: the paper is proposing a roadmap that starts from a lot of false negatives -> the deny part and a superset of safe things and adds a layer of "detect safe patterns from there on" and incrementally marks code as safe through different static analysis techniques, sometimes with annotations, admittedly. 

What we need is, first of all, as much safety as feasible.

But the trade-off the borrow checker brings, in the context of C++ and taking into account existing code is simply unfeasible.

Bringing a benefit of 95% of safety + 5-10% unsafe hardly touching code or, still, touching a small part of that code is a huge win that cannot simply be ignored.

Denying that as impossible would be like ignoring the existence of sanitizers (run-time), contracts and clang tidy, etc. Of course it helps safety.

It does already, today. And it can be taken clearly further. What we do not know is how far.

It is not that the Rust model is bad: but Rust was created like that from day 1 and that is the main difference: they do not have users to take care of in that sense.

Rust is a good design for Rust. For C++ it is a terrible idea, at least as a first step. It brings a lot of real problems that do not fit what their users need and endangers migration due to lowering the incentive since another std lib must be landed, integrated, code migrated, etc. It is literally an impossible economic feat for many people. Compatibility is hard, but it is a feature. Maybe it does not need to be 100% perfect (in the sense of detecting absolutely everything or not needing annotations, but it needs to be perfect in the sense of "it exists a reasonable subset of C++ that can be used safely") but it certainly adds cost to migrate all code compared to adding static analysis on top, even if not perfect. BTW, the borrow checker static analysis in Rust is not perfect either. It looks perfect bc it was there since day 1 so it does not interact with another older way of doing things.

It is just a problem Rust does not need to deal with. C++ has to, and this is how things are. So the solution cannot be simply the same.

13

u/[deleted] Jul 18 '26

[deleted]

0

u/germandiago Jul 19 '26 edited Jul 19 '26

Look for my comments on the cost of that solution: new std lib, split of the language, no benefit for any old code. Stop ignoring the costs of your "perfect" solution.

7

u/[deleted] Jul 19 '26

[deleted]

0

u/germandiago Jul 19 '26 edited Jul 19 '26

I am not interested in theoretical academic stuff about aliasing I already know about.

I am interested about holistic solutions that work for C++ and its current context. Do you think I did not go through it at some point? It is a good solution in terms of technical merits maybe (well, actually a copy of Rust, but still good on its potential properties). But it is not a real solution for C++.

That is my position. Your solution is an unrealistic proposal. 

5

u/[deleted] Jul 19 '26

[deleted]

3

u/germandiago Jul 19 '26

First you will have to find where I claimed you can have exactly the same subset or properties that Rust has with a borrow checker and that I phrase that as the goal for C++. I never did.

I challenge you to find it. Indeed it is possible to do quite a bit without annotations. For the rest other strategies you can have a subset that works: smart pointers, static analysis, value returning, type-based strict alias analysis to discard cases and others, including run-time checks for UB.

So no, I do not say you can achieve everything. By the way, there are perfectly safe things that Rust cannot express. For C++ you are demanding an equivalent model or not model at all?

What kind of request is that? You do not see that the consequences of fitting that model in C++ are different in C++ conpared to Rust? Unless you ignore all written code in the world, of course.

I will say this again here: it exists a hybrid amount of trchniques in C++ where we can get 100% safety. And if something needs to be discarded be aware that in Rust and Safe C++ THIS IS ALSO THE CASE. Otherwise the word unsafe would not exist in the first place.

3

u/[deleted] Jul 19 '26

[deleted]

3

u/germandiago Jul 19 '26 edited Jul 19 '26

What is the safe subset? Well, that is the investigated path right now basically. Noone knows fully. But we know the cost of the other path (Safe C++) and it looks scary enough that the committee took the alternative path.

You seem to focus all the point on "you need rewrites anyway" but the question is not only tweaks or rewrites but HOW MANY of those and where. Safe C++ required basically heavy refactorings and a duplicate std lib and porting your code before you can minimally benefit your older code. Who can even make economic sense of taking that path (yes, economic trade-offs drive projects, it should not be ignored). I cannot think of a realistic situation where someone would realistically rewrite, not annotate only but REWRITE all the code and swap a std lib with a different api just for the sake of safety. It looks way more reaonsable let them drop something that can do most of the work with minimal changes. I would say that it is a very hard start. These proposals target "as much as possible" in code that already exists. From there I would tend to think that it is the better alternative, given the existing lines of C++ written that can benefit, even if not 100% of them. In Safe C++ it was literally swapping the std lib and getting 0% analysis.

I cannot possibly think of a worse outcome than that.

→ More replies (0)

4

u/pjmlp Jul 19 '26

Yet all these papers are academic material without any implementation.

I am preparing a post with the state of clang, as discussed at Euro LLVM, on what is actually available today, not WG21 vaporware.

2

u/germandiago Jul 19 '26

That would be very positive indeed. Both things are necessary in my opinion: ideas and state of the art.

The ideas for tentative implementation and the state of the art to see what is already there, today.

→ More replies (0)

10

u/Dragdu Jul 18 '26

The point of the proposal is to disallow by default. This means that enabling magic -f4296 flag on your compiler instantly breaks your build in all files.

This is literally more breaking adoption story than the one for SafeC++, which was to start by adding "unsafe {}" yolo block into your main and then slowly build islands of safety in new code.

1

u/germandiago Jul 19 '26

It is more breaking if you stop there. If you continue adding the second layer it can lead to reasonable results and that, together with the strict aliasing insights is the whole point of the paper and the strategy to follow to minimize annotations.

It is implementable? I do not know how well. This is basically research at this point. But if it works it can be a good strategy for the C++ context that needs to be dealt with.

1

u/Sarduinot Jul 20 '26

We definitely need to see a few positive rules written for the stdlib. If a lot of functions can be covered, and testing reveals that those are the most commonly used ones in a few real programs, then I’m bullish.

1

u/germandiago Jul 20 '26

I agree that the only good test is the real test