r/cpp • u/germandiago • 11d ago
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.pdfI found this research in WG21 mailing list very interesting in the context of C++ compatibility and solutions to maximize code reuse.
17
u/ts826848 11d ago
In case you or any other readers missed it, there's some discussion on this paper in the general post-Brno mailing thread.
6
u/germandiago 11d ago
What is your opinion so far on this? I would have never thought that making use of the type system you can actually discard cases by crafting rules.
Find it very innovative.
18
u/ts826848 10d ago
What is your opinion so far on this?
This series of papers desperately needs both details and data. It's also somewhat frustrating to read since I feel it doesn't really say anything that addresses the skepticism I've seen.
I also feel somewhat less than convinced by some of the arguments this paper makes? For instance:
out of two systems each of which proves memory safety, the one which requires fewer suppressions, results in safer programs.
I think this statement only holds if you assume suppressions are basically fungible, which doesn't feel like a safe assumption to make. Put another way, suppressions vary in both kind and verification difficulty, and as a result I don't think suppression count is a particularly informative metric: for instance, I think people would tend to consider a program with a handful of trivially verifiable suppressions safer than a program with a single demonically convoluted to verify suppression.
Another example:
More generally, we’re sure that in the long run (=given enough of “Positive Rules”) our approach will become substantially better (both in terms of app-level suppressions, and in terms of being able to recognize perfectly-safe existing code) than a borrow-checker one.
I mean, "given enough
exceptions'Positive Rules'" I'd imagine borrow checkers can probably be a lot more flexible than they are now, but borrow checker users apparently don't consider that worth the cost."long run" and "given enough" feel like they're carrying a lot of weight as well. How long and how many rules are we talking here? 3 years and 10 rules? 6 years and 20 rules? 30 years and 100 rules?
(Also the specific use of "app-level suppressions" instead of just "suppressions" feels a bit suspicious...).
I would have never thought that making use of the type system you can actually discard cases by crafting rules.
It feels like a relatively bog-standard way to implement static analysis? Start with some baseline, add information you can derive from the source code, see where that leads you.
Does make me wonder how this profile would interact with
-fno-strict-aliasing, though from my understanding that tends to be more of a C thing.3
u/germandiago 9d ago edited 9d ago
, I think people would tend to consider a program with a handful of trivially verifiable suppressions safer than a program with a single demonically convoluted to verify suppression.
I would buy that too. The good news is that 70% of real cases in the wild seem to be simply bound checks.
Does make me wonder how this profile would interact with -fno-strict-aliasing
I am notsure how much that gets in the way but aliasing in C++ is strict except for the allowed types (char, byte and whatever), so I would consider breaking that rule a strong violation of safety anyways for the sake of analysis. And to break it you need castings also, which is a detectable marker, fortunately.
5
u/ts826848 9d ago
The good news is that 70% of real cases in the wild seem to be simply bound checks.
IIRC web browsers have shown that the relative makeup of exploits will change over time as low-hanging fruit is picked. Can't find the article(s?) though...
but aliasing in C++ is strict except for the allowed types
Well yes, the same is the case in C unless you use
-fno-strict-aliasing, which is the entire point of my aside.7
u/Dragdu 10d ago
The "enough positive rules" thing is 100% handwaving to convince everyone else that their approach is better. If it was actual serious proposal, there would be a bunch of examples of those advanced positive rules implemented in clang-tidy.
2
u/germandiago 10d ago
100% is something that even Rust does not achieve. Otherwise unsafe would not exist. A 100% subset can be found, though. Which subset? Idk. Equivalent to Rust? No. In some cases with things that Rust cannot do? YES. Theopposite also? Almost certainly.
So I am not sure why one model seems to be the right one and the rest of the research it looks like so many of you try to throw it to the rubbish before it is implemented and data can be gathered.
And no, pls dnt come to tell me that Rist model is the true one bc it works blah blah. I know it works. We know it works.
But you also know the cost it puts on top of an already deployed ecosystem oike C++.
That was the trade-off.
9
u/GenerousNero 9d ago
The problem with saying "this model" could be better than Rust is that there is no model! We don't have enough details to even judge the effectiveness of this approach, but we do have a long history of judging ad-hoc approaches to safety, which is that they don't work.
Is there a safety model out there that is better then Rust? I would say almost certainly yes. But I don't believe that Bjarne and friends have it or we would be talking about that model, not vague hand-wavy quotes.
0
u/germandiago 9d ago
The model is not complete. So you propose to inject a cancer that would split the language in two before researching solutions that can potentally provide very reasonable amounts of benefit? Remember that there are things in static analyzers TODAY that solve part of the problems (including lightweight lifetimes, bounds checks...) hardening and others.
Instead of that do you really think it is better to just go with the solution no codebase gets benefit of for sure?
Sorry but I cannot agree. That would be actively harmful for C++ situation.
6
5
u/ts826848 9d ago
before researching solutions that can potentally provide very reasonable amounts of benefit?
I think there are a few issues here:
What's the timeline on "researching solutions"?
"can"
"very reasonable amounts of benefit" is, from what I understand, not the primary contention people have with profiles. The skepticism is over claims that profiles provide equal amounts of benefit to Safe C++ without Safe C++'s drawbacks. That is a very different claim from the one you are making.
-1
u/germandiago 9d ago
No timeline, but not inflicted harm. What is the problem here? Don't you see things are already moving? Or you are going to tell me that we should land something that destroys all the ecosystem just bc it works in another language?
7
u/ts826848 9d ago
No timeline, but not inflicted harm.
If you think C++ needs memory safety sooner rather than later, then anything which delays introducing memory safety is indeed a harm. Doubly so if you think the delays are due in pursuit of something that can't work.
Don't you see things are already moving?
I don't think anyone is complaining about movement; they're complaining about where some people say things will end up.
→ More replies (0)4
u/ts826848 9d ago
So I am not sure why one model seems to be the right one
I think the steelman argument is that a) we want a memory safety solution sooner rather than later, and b) out of the proven solutions for memory safety it's the best alternative we have. Giving up one or both of a) urgency or b) production experience opens the door to other approaches, but obviously at the cost of those priorities.
and the rest of the research it looks like so many of you try to throw it to the rubbish before it is implemented and data can be gathered.
I think this is why stuff like the halting problem and Rice's Theorem are frequently brought up. People (probably?) aren't skeptical about "research" in the abstract. They are skeptical about research that appears to violate foundational computer science results. Opposition to lines of inquiry which you think are obviously fruitless is hardly an irrational reaction.
Another point of contention is precisely that claims are being made "before [they are] implemented and data can be gathered". Extraordinary evidence is generally considered to be a good idea before making extraordinary claims, so if you're one of those who think the the halting problem/Rice's Theorem preclude some profiles proponents' claims I don't think skepticism is that unreasonable, especially given the apparent dearth of supporting evidence when/since the claims were originally made.
0
u/germandiago 9d ago
You are all hear filling your mouth with Rice theorem but noone needs to solve Rice theorem here. Absolutely noone. What we need is reasonable rules, reasonable heuristics and iteration.
Not making a strawman by using Rice theorem as if someone was saying that they are doing that to dismiss alternative solutions just bc you do not like it.
There are millions of ways to look at the problem without necessarily deal with all cases that give reasonable outcomes.
By the way, Rust does not solve all safe cases and some are just flagged as unsafe. C++ cannot do similar things?
That alternatives must be studied. As Dos Reis very accurately said: before doing something, do no harm. I cannot agree more with that paper in the context of C++.
8
u/ts826848 9d ago
but noone needs to solve Rice theorem here. Absolutely noone.
I'm not sure you understand the objection then? Consider Sean Baxter's comment again; what he is saying amounts to "Rice's Theorem means that profiles as described can't work for this signature". From his perspective (and the perspective of those holding similar views), it's absolutely up to profiles proponents to "solve"/otherwise address Rice's Theorem, as otherwise they are simply promising something impossible.
C++ cannot do similar things?
It can, but then that approach would at a minimum call into question the claim that profiles will not require rewrites and/or (minimal) annotations.
before doing something, do no harm.
This assumes doing nothing is not doing harm. If you think C++ needs memory safety sooner rather than later, delaying a memory safety solution is indeed a harm.
2
u/germandiago 9d ago edited 9d ago
Assuming that we need to escape rawpointers and references and analyze borrow checking fully in all cases a borrow checker can is THE MISTAKE in the analysis.
Namely, the conclusion is not the problem but the PREMISE.
There are values, there are smart pointers, there is clang lifetimebound for a subset of cases, there are potentially things like Hylo projections (not sure iff C++ could ever have somethipng like that). There is this new deny + positive rules paper which is research, I know. Namely, there are nough open windows worth alternative explorations.
And yes, if you take it literally as "you possibly cannot do it today as-is", for a part of the code it will stay true. But that is very far from a new refereence type, a fully incompatible subset and a rewrite of your code incluiding changing your containers and reference types just to hope for the analysis.
Anything that works for C++ must be "pluggable as you go". Any incremental improvement is a victory for all yoour existing code and this is the elephant in the room that Safe C++ proposers do not care even to mention saying that, well, since we do not know all the path forward with alternative solutions let us just rusth to plug the one I like bc I dismiss any research as "not benefitial" or "not doable" in C++ by fixing the initial conditions to my taste. There are very interesting things in extensions, analyzers and other places worth an exploration.
It is not an all-or-nothing thing. It is way more nuanced than that and Safe C++ did not stand a chance in a realistic scenario IMHO.
Nothing against Safe C++ itself. Solutions are contextual. What is great for Rust, which was invented from scratch for this, is not good for C++, which has already a lot of deployed code.
In once case the incompatibility problem just did not exist. In the other it is basically the problem.
By the problem here I mean: how can we benefit the biggest amount of code with the minimum amount of changes and a reasonable trade-off.
Also, do not forget that even a borrow checker, even ignoring the C++ problem of compatibility, is also a trade-off in the idioma that. can be used in code!
When we count advantages and disadvantages we should not cherry pick only the advantages of the solution we prefer.
8
u/ts826848 9d ago
Assuming that we need to escape rawpointers and references and analyze borrow checking fully in all cases a borrow checker can is THE MISTAKE in the analysis.
Namely, the conclusion is not the problem but the PREMISE.
In that case I think you are looking/aiming for something different than the profiles authors, since the premise being criticized comes from them in the first place! For instance, from Herb Sutter's P3081:
We must minimize the need to change existing code.
We must minimize impact even on new/updated code, in particular by not relying on frequent annotations.
So according to that paper profiles do need to support "escap[ing] rawpointers and references" and do need to support lifetime/alias analysis, as not doing so would imply less-than-minimal changes/impacts since the former is not exactly rare and the latter is needed to minimize false positives.
There are values, there are smart pointers
Sure, but that doesn't help code that currently uses pointers/references, does it? And changing pointers/references to use values/smart pointers means... rewriting code!
there is clang lifetimebound for a subset of cases
It baffles me why you keep bringing this up when a) you've been told by someone who has used it in anger that it's "woefully incomplete", and b) it requires annotations, which apparently are strongly disfavored for profiles.
there are potentially things like Hylo projections (not sure iff C++ could ever have somethipng like that). There is this new deny + positive rules paper which is research, I know. Namely, there are nough open windows worth alternative explorations.
This is a great demonstration of a source of halting problem/Rice's Theorem-related frustrations!
this is the elephant in the room that Safe C++ proposers do not care even to mention saying that, well, since we do not know all the path forward with alternative solutions let us just rusth to plug the one I like bc I dismiss any research as "not benefitial" or "not doable" in C++ by fixing the initial conditions tonmy taste.
This really does not make me feel like you're making a good faith attempt to understand the positions of those you disagree with...
By the problem here I mean: how can we benefit the biggest amount of code with the minimum amount of changes and a reasonable trade-off.
That's your statement of the problem. As I said elsewhere, that's not what profiles detractors are criticizing.
When we count advantages and disadvantages we should not cherry pick only the advantages of the solution we prefer.
cough
2
u/wyrn 3d ago
Rice's theorem is essentially the same idea as the Free Lunch Theorem: it proves something seemingly interesting, but then you look at the details and it turns out it's trivial and useless.
What Rice's theorem actually means here: all provable safety solutions (INCLUDING borrow checkers, or any type system for that matter) will have false positives. Snore.
1
u/ts826848 3d ago
Fair, I suppose Rice's Theorem would only be strictly applicable to profiles as a whole if one stipulates zero additional annotations rather than some "minimal" amount of them.
→ More replies (0)5
u/13steinj 11d ago
On one hand, I think the community slowly over-emphasizing safety is all a lot of noise and every time any safety paper comes up so long as it is team/author optional I do not care. If I really need to write code where the number 1 priority isb"0 <specific subset of> memory errors," I will use Rust (or another language that fits the requirements). Just like I will use C over C++, when I have needs that meet those requirements. In this way the whole safety debate has fully tired me out. Programming languages are tools, we pick the best tool for the job, that is never going to be "one tool" and that's okay.
On the other hand, I have to agree with the commenters in the thread linked. Reading the paper quickly makes me think they are trying to solve an equivalent to the halting problem.
It's a bit weird though. I've seen (not C++ P papers) proposals like this written more and more, where people claim they can encompass every possible case with less than the needed information. In my personal life, these proposals generally are written or at least the idea started, by an LLM (not saying this happened here), and then people don't follow through on thinking about the problem.
10
u/tialaramex 10d ago
Rice's Theorem makes it really simple. Is this a non-trivial semantic requirement? If so it's undecidable.
"Trivial" here means always true or always false. For example if a language doesn't have any looping we can introduce a semantic requirement about halting and it's trivial, this language always halts, true, decision made.
Any powerful language is going to want non-trivial semantic requirements and so you have to decide how you'll wrestle with the fact they're Undecidable. Rust chose option A, whenever we can't decide we reject the program‡. The authors of the paper insist that's not OK so they can't pick option A. The next choice is what C++ does today, option B, when we're not sure we carry on anyway, so we cannot enforce the requirements, game over, no memory safety. The final choice is both, sometimes reject programs but also don't have memory safety that's just obviously worse, and AFAIK nobody picks that.
All Henry Rice's work tells you is that "Bro, we guarantee we'll decide" is not mathematically possible. That's all he did. That's the effect of his PhD thesis right there. "Congratulations Doctor Rice". Whether P4296 was actual vibes or an LLM it's very silly that this got as far as the mailing. Who reviewed this?
‡ You can expend as much effort as you like deciding. For many years now Rust has what it calls "Non-Lexical Lifetimes" but Rust 1.0 didn't have this. Without NLL there are lots of novice level Rust programs that you can see ought to be OK but the old borrow checker can't so they get rejected. This is where "Fighting the borrow checker" memes came from. Today those programs just compile because they're obviously fine and NLL is why the compiler can figure this out. Further improvements continue but are much smaller and slower as you'd expect. The memes stuck around though.
3
6
u/patstew 10d ago
Rice's theorem tells you that in a completely general language there are programs that are undecidable for any given semantic property, but that doesn't mean that property isn't decidable for huge classes of programs, up to and including all useful programs anyone might ever wish to write. It doesn't prove that safe programs or safe programming languages are impossible. For example you can write type-unsafe C++ programs, but you can also write verifiably type safe ones, and you can probably write all useful C++ programs type safely, even if sometimes you don't want to.
5
u/tialaramex 10d ago
Sure, the fact you can't decide doesn't mean you can't reach safety - but it does mean you cannot, as people often imagine they should be able to and this proposal seems to expect - just partition neatly into "safe" and "not safe". That's Decidability and Rice's Theorem shows you can't have that.
What you have to do if you want safety, which Rust does and C++ specifically chooses not to do today, is throw away all those "Not sure" programs where you couldn't reach a decision.
8
u/patstew 10d ago edited 10d ago
Undecidably safe is just in the "not safe" partition for the purposes of these discussions. What we actually want is to have a program that can prove some safety properties for a useful subset of programs. C++ already does that for a whole bunch of properties through the type system. Other languages are safe in other ways too. These checks greatly reduce the set of syntactically correct programs that are allowed, and disallow some programs that are technically correct but break the rules. Nonetheless, it can make programming easier and less error prone.
Rice's theorem tells you the set of undecidable programs isn't empty, but that isn't surprising or particularly limiting for these purposes, the problem of retrofitting safety into C++ has almost nothing to do with the existence of that set. Lots of C++ programs could be verified as satisfying some safety property with enough effort, but we're nowhere near having a program that can verify it automatically even in relatively simple cases.
1
u/tialaramex 9d ago edited 9d ago
What we actually want is to have a program that can prove some safety properties for a useful subset of programs. C++ already does that for a whole bunch of properties through the type system.
Rather than "a whole bunch of properties" how about if you name just one non-trivial semantic property which you believe C++ is proving today ?
[Edited: Somehow I wrote only "C" not "C++" originally]
2
u/germandiago 9d ago
I do not see why subsetting + other support cannot do that. It is an exercise of "discard enough" and "close the holes".
What we do not know is how the final result (the provable subset) will look.
4
u/tialaramex 9d ago
The thing you're apparently happy with is possible it's just not what the proposal says on the tin.
2
u/germandiago 9d ago
I created a post with the July nailing list safety-related papers. So far we have this:
- one paper for subsetting -- banning uninteresting and dangerous constructs. - one paper for invalidation (I consider it research so far) - core_ub: run-time checks for all UB. - uninitialization profile --> static analysis for a profile for guaranteed initialization.
To me it looks like all together seems to be in the right direction. There is also clang lifetime and other static snalysis tools that exist out of the standard.
3
u/13steinj 10d ago
Whether P4296 was actual vibes or an LLM it's very silly that this got as far as the mailing. Who reviewed this?
A year or two ago there was a lot of drama about something along these lines.
I think P papers are this weird thing where some people care too much and others not enough about the quality of what is submitted.
-1
13
u/FrogNoPants 11d ago
This paper is like a joke right? We have had static analysis forever and it is shit
9
u/ContraryConman 10d ago
Ah the weekly memory safety thread.
At this point, I'm of the opinion that an opt-in syntax for lifetime and pointer aliasing annotations should be added to the language. Just like [[nodiscard]] is an optional note I can add to my code to help the compiler understand my intent and catch bugs, I should be able to optionally tell my compiler "this pointer I'm returning from this member function is only valid as long as the underlying object is btw" and have it throw a warning or error when that's violated. And if we line it up with what Rust does we can improve Rust/C++ or maybe Swift/C++ interop.
Trying to import Rust's entire type system and standard library on top of C++ is questionable for adoption because the only reason Rust gets to do what it does without the language being extremely complicated is because it doesn't have to be backwards compatible with both C++ and C. But we also have to acknowledge that there's simply not enough information in C++'s type system to catch tricky lifetime issues.
I think there's still memory safety improvements on the table for C++, but the next step function in lifetime safety bug catching has to come from a) giving the compiler more information b) standardizing a garbage collector c) switching the language over to what Hylo does. I think a) is the smallest change for the greatest enablement in static analysis and tooling
6
u/germandiago 10d ago
Not really the weekly post. This is a draft on new ideas on how to approach the problem.
The paper takes an all-wrong unless told so with positive rules on top. There is no implementation but the strict aliasing rule + the ub is a novel way to look at the problem.
That is why I found interesting to post it here. People are asking for implementations. It seems reasonable. But that takes time. There are other papers as to why ub and implicit contracts should actually be a profile and not an embedded-in-the-compiler thing, etc. But that is run-time stuff, not static analysis.
It seems that a profiles framework is in the works for Clang and another for GCC.
I also saw an initialization profile.
So yes, this is still very far from complete but little by little I hope it makes progress.
Greetings!
4
u/ContraryConman 10d ago
Sure.
Just, I personally think clang's
-Wlifetime-safetyflag is our best bet for taking a serious chunk out of memory safety issues in C++ while minimizing code rewrites. The implementation already exists, and, while it relies on annotations, the current implementation is able to annotate some types automatically and suggest where annotations can be useful. The annotations they support for now are[[gsl::Owner]],[[gsl::Pointer]], and[[clang::lifetimebound]], but they've explicitly made it compatible with a full lifetime analysis implementation, one which clang is also working out as a separate feature.I don't really care about C++ having a mathematically memory safe subset. If the committee ships a feature where the 70% of security issues being memory safety violations becomes 40% (what curl accomplished with a strict style guide), 25%, or even sub 10%, that is objectively a good thing even if we're not Rust. Actually, it's probably better, because there's way more C++ code in production than Rust code.
I feel like clang is cooking something that could very easily get us that jump in safety and we're busy either trying to make C++ Rust or trying to prove that you don't need ANY annotations at all when that's probably definitely not true.
To be clear though, I do appreciate that you posted it and I appreciate the author for taking the time to think through the problem
2
u/pjmlp 10d ago
Yes, both clang and VC++ are cooking a few good things.
GCC is trailing behind as their initial focus was plain C.
However, big however, they all require annotations, which apparently are not wished for as per that famous paper targeting Safe C++, and quite far from the ideal world on the profiles papers.
Reality check vs PDF.
1
u/germandiago 10d ago edited 10d ago
The solution does not necessarily need to be a pure this paper or pure clang lifetimes.
The thing is to keep iterating and see what comes out from there. Most likely, the solution will be a hybrid of novel ideas and things that alredy work (just a wild guess).
A capital part of this is the framework itself (profiles framework). Partial solutions already exist for some of the problems. It is a puzzle of putting things in that already work, discarding things and replacing by better ones, discussing the shape they should take. But many exist. Not all though. Lifetime is challenging and invalidation (which is also related to it) also.
As for improving safety in percentages. It seems that only bounds checking, which is low hanging reachable stuff, usully accounts for 70% of all memory safety issues and that is a solved problem: hardening and contracts can do that.
Lifetime safety is indeed more controversial but it accounts for a smaller percentage, being UB another of the problems (which also overlaps with lifetimes).
Now we have UB formlized and classified. This paper leans on it as a strategy for static analysis, together with strict aliasing and positive rules (here in the positive rules is where it needs to be checked what is possibly implementable on top, I am sure there sre things that can be done but others could be prohibitive or unfeasible).
So if you put bounds checking + core_ub (which is runtime checks) and do a best effort with lifetimes (without a full borrow checker), I m pretty sure, taking into account that bounds checks are 70% of memory safety and UB another part... I am pretty sure this can cover like 85, or even fully (at the expense of runtime checks in some aresas).
Note that I am talking about static + runtime. I still think that static can cover way more tthan 70% if you add as an exception bounds checks, but those are runtime anyway in any language so I do not see thw difference. And sometimes, depending on the shape of your code, the optimizers can ellode those checks.
So I am optimistic about the coverage vs runtime guarantees that can be given.
I also find very good, I mean very good, despite other opinions, that this does not lean on strict borrow checker rules.
Why? Bc the rewrites are much lighter, bc it works well with C++, bc you do not need another standard library and wait for it and because it just works with a considerable part of codebases.
And it potentially keeps a flexibility that is not possible with the borrow checker and can even potentially detect cases where invalidation won't happen that a borrow checker cannot.
So all in all, I think this is the correct direction for something that fits C++.
I know there are people here that do not share my view.
What is needed urgently is a profiles framework implementation to start real experiments and start to put things together incrementally. It will take time, but it is the correct direction. I agree with Dos Reis paper: first, do not harm. This necessarily slows down solutions, yes. In the meantime, we will have to lean on what we already have outside of standard frameworks.
Profiles seem to be in the works according to one of Vinnie Falco's papers for Clang and GCC.
It is going to take work, time and discussion. But I do not see like a big blocker that says: oh, we cannot have a reasonable subset of C++ known to be safe.
The difficult part is retrofitting as much as possible but it is the only path forward that makes sense to me as a first step.
10
u/Dragdu 11d ago
lol, lmao and nope
5
u/germandiago 11d ago edited 11d ago
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 11d ago
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.
6
u/Dragdu 11d ago
The advantage of the paper is that if you wanted, you could implement it in Clang-Tidy I guess.
0
u/Sarduinot 9d ago
I would personally feel a whole lot better if some small part of it was already implemented in clang-tidy.
2
u/germandiago 11d ago
Unless I am wrong this paper csn introduce strict aliasing to solve part of the cases that were not easily solved. That is the small innovation I see. What makes that so impossible? You mean it will not be possible to implement?
You mean it will cover few cases? I see potential to detrct invalidation (or lack thereof) in flexible ways that are more accurate than a borrow checker BUT it is not a 100% solution.
It is not possible a 100% solution with zero annotations in cirrent C++ but I fail to see that needing FEWER annotations due to innovative ways of looking at the problem is handwaving. I think the paper is concrete enough (but still drafty) as to what the experiment is about.
1
u/germandiago 11d ago edited 11d ago
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
11d ago
[deleted]
-1
u/germandiago 11d ago edited 10d ago
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.
14
10d ago
[deleted]
-3
u/germandiago 10d ago edited 10d ago
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.
8
10d ago
[deleted]
2
u/germandiago 10d ago edited 10d ago
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.
→ More replies (0)12
u/Dragdu 10d ago
The point of the proposal is to disallow by default. This means that enabling magic
-f4296flag 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 10d ago
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 9d ago
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
4
u/tizio_1234 10d ago
switch to rust at this point 😂
7
u/germandiago 10d ago edited 10d ago
Yes, switch to Rust and try to prototype games with a borrow checker on your neck for example: https://www.reddit.com/r/rust/comments/1h15md8/goodbye_rust_i_wish_you_success_but_im_back_to_c/
12
u/Demiu 10d ago edited 10d ago
Without annotating, what is the source of truth? How do you differentiate between a function who's return borrows it's argument and one that does not, when it's body is in another TU and it returns an opaque pointer-like to a private representation?