3 ms·
I only mentioned undefined behavior. Memory safety is a subset of those issues, but rust's actual promise is eliminating all UB in safe code. In almost all cas
by AlotOfReading 2y ago
I only mentioned undefined behavior. Memory safety is a subset of those issues, but rust's actual promise is eliminating all UB in safe code.
In almost all cases for preconditions, that's solvable by better practices that could be identified in a review. It's the same underlying problem as C, but dramatically more manageable.
And of course, any C is liable to be misused in C++ where the committee's current position is that the problem is unsolvable.
- uecker 2y agoIt is the same problem in C and more manageable. I just doubt the "dramatically". And C problems also become more manageable with better tools and more focus on safety in the language evolution.
- AlotOfReading 2y agoI completely agree that C and C++ become more manageable with modern tooling. The problem is that better doesn't fundamentally change the situation. How UB is defined in the standards means semantics are an all or nothing situation. Either there's no UB and you have the semantics specified by the standard, or you have UB and no semantics (past the point of UB in C23 thanks to your proposal). We've had a solid 30 years of history demonstrating that exhaustive static detection is impossible and every nontrivial program has UB of some kind. You can't fix this with minor changes in the language or improved tooling. You need a complete overhaul of how the standards and implementations deal with UB.
- uecker 2y agoBut Rust shows that static detection is possible if you add constraints to the language, and this is exactly what one can do it C too. Rust was inspired by a C dialect after all. The situation with UB is not actually as bad as it sounds (I analyzed all UB in the core language).
- AlotOfReading 2y agoIgnoring memory safety where rust's solution is more obvious, the lack of UB in Rust is mainly the result of consciously deciding to eliminate it. Signed overflow is implementation defined for example. The parsing UB that takes up half of annex J is eliminated by simply expecting that implementations write proper parsers and having a better macro system. Invalid enum values were solved by a stronger type system. If there were actually an appetite to eliminate it, I suspect we could probably eliminate 70% of J.2 with a few straightforward changes. Many of these aren't completely amenable to static analysis, like signed/shift bounds, but they're workable at the language level. The members of the C++ committee I've talked to were skeptical about the actual chances here though. The rest of annex J is at least partially addressed with existing efforts like checked C and Coral ("constraints"), so at least there's a path forward with tooling.
- uecker 2y agoThe things you mention are already ongoing. We eliminated 15 items in J.2 in last meeting and will remove more in the next. Not that I agree that the UB is really the that much of a problem, only very specific cases of UB actually cause real safety problems.
- AlotOfReading 2y agoIn my domain (safety critical), I'm interested in taking a piece of code I didn't necessarily write and making statements about the state of the system at various points in the execution. It doesn't matter whether the UB that exists doesn't result in observable misbehavior of the system as it exists today, I also need to ensure that the system will continue behaving in 10-50 years with a different compiler on a different architecture that may not even be designed yet. Currently, all of that work has to come with a little asterisk saying "except for undefined behavior". I can't constrain where UB might be in the system, or how it might violate the safety model. In short, if I do my job properly I shouldn't assume C/C++ semantics at all. Obviously that's not reasonable, so everyone goes around pretending this isn't an issue to their safety models and their regulatory filings and so on. Obviously I think that's wrong, but there haven't been ways to address it in C and C++. It's possible in Rust.