4 ms·
> No. I'm talking about a mechanism that can detect various errors at runtime, and is turned on or off for various pieces of code and/or for all code at various
by pcwalton 7y ago
> No. I'm talking about a mechanism that can detect various errors at runtime, and is turned on or off for various pieces of code and/or for all code at various stages of development
What you are describing exists: ASan. We have a pretty good answer to the question "is ASan sufficient to prevent memory safety problems in practice": "no, not really".
> Rust, BTW, doesn't entirely guarantee memory-safety, either, when any unproven unsafe code is used, and even when it isn't (e.g., have you proven LLVM's correctness?). We always make some compromises on soundness; the question is where the sweet-spots are.
Empirically, Rust's approach has resulted in far fewer memory safety problems than previous approaches like smart pointers and ASan, with only garbage collectors (and restrictive languages with no allocation at all) having similar success in practice. Notice that the working approaches have something important in common: a strong system that, given certain assumptions, guarantees the lack of memory safety problems. Even though those assumptions are never quite satisfied in practice, empirically having those theoretical guarantees seems important. It separates systems that drastically reduce safety problems, such as Rust and GC languages, from those that do so less well, such as ASan and smart pointers. This is why I'm so skeptical of just piling on more mitigations: they're helpful, but we've been piling on mitigations for decades and UAF (for instance) is still a big a problem as ever.
- pron 7y ago> We have a pretty good answer to the question "is ASan sufficient to prevent memory safety problems in practice" That is not the question we're interested in answering, and elimination of all memory errors is no one's ultimate goal, certainly not at any cost. By definition, unsound techniques will let some errors through. The question is which approach leads to an overall safer program for a given effort, and soundness (of properties of interest) always comes at a cost. (also, Zig catches various overflow errors better than ASan) > Empirically, Rust's approach has resulted in far fewer memory safety problems than previous approaches like smart pointers I don't doubt that, and if minimization of memory errors was programmers' primary concern (even in the scope of program correctness or even just security), there would be little doubt that Rust's approach is better. As someone who currently mostly programs in C++, lack of memory safety barely makes my top three concerns. My #1 problem with C++ is that the language is far too complex for (my) comfort, where by "complex" I mean requires too much effort to read and write. That, and build times, have a bigger impact on the correctness of the programs I write than the lack of sound memory safety. Would I be happier if, for a similar cost, I could eliminate all memory safety errors? Sure, which is why, if C++ and Rust were the only low-level languages in existence, I'd rather people used Rust. But I would be happier still if I could solve the first two, and also get some better safety as a cherry-on-top. Memory safety is similarly not the main, and certainly not the only, reason I use languages that have a (tracing) GC when I use them.
- apta 7y ago> As someone who currently mostly programs in C++, lack of memory safety barely makes my top three concerns. Isn't having a UB-free JVM a noteworthy goal though? Especially if it gets used in life-critical systems such as avionics or autonomous cars.
- pron 7y agoUB-freeness is not a goal in-and-of-itself. It's shorthand for a certain kind of technical (i.e. non-functional) correctness, which, in turn, is related in some ways to functional correctness, and it's improving functional correctness (and I include security here) that's the goal. Is the most effective way to achieve that is by working to completely eliminate undefined behavior? I'm not at all sure.
- pron 7y agoP.S. > Notice that the working approaches have something important in common: a strong system that, given certain assumptions, guarantees the lack of memory safety problems. That's a very good point and I'm not arguing against it. It's just that even if it's true -- and I'm more than willing to concede that it is -- it still doesn't answer the question, which is: what is the best approach to achieving a required level of correctness? The "soundness" approach says, let's guarantee, with some caveats, certain technical correctness properties that we can guarantee at some reasonable cost. The problem is that that cost is still not zero, and my hypothesis is that it's not negligible. My personal perspective is that Rust might be sacrificing too much for that, but that's not even what has disappointed me with Rust the most. I think -- and I could be wrong -- that Rust sacrifices more than it has to just to achieve that soundness, by also paying for "zero-cost abstractions," which, for my taste, is repeating C++'s biggest mistake, namely sacrificing complexity for the appearance of high-level abstraction that may look convincing when you read the finished code (perhaps more convincing in Rust than in C++), but falls apart when you try to change it. Once you try to change the code you're faced with the reality that low-level languages have low abstraction; i.e. they expose their technical details, whether it's through code -- as in C and Zig -- or through the type system, as in Rust. Zig says, since the abstraction in low-level languages is low anyway (i.e. we cannot really hide technical details) there is little reason to pay in complexity for so-called zero-cost abstractions. Language simplicity goes a long way, even as far as sound formal verification is concerned. For example, there are existing sound static analysis tools that can guarantee no UB for C -- but not the complete C++, AFAIK -- with relatively little effort. It's not yet clear to me whether Zig, with its comptime, is simple enough for that, though. It is my great interest in software correctness, together with my personal aesthetic preferences, that has made me dislike language complexity so much and made me a believer in "when in doubt -- leave it out."