4 ms·
I do think the 'unsafe' notation is the crucial bit here. Rust has stuff that is heavily (although not completely) motivated by C interop. For example, 'union'
by burntsushi 4y ago
I do think the 'unsafe' notation is the crucial bit here. Rust has stuff that is heavily (although not completely) motivated by C interop. For example, 'union' in Rust is something that is rarely used outside of C interop. (With some notable exceptions in the standard library.) But, crucially, in order to actually use a Rust 'union', you do have to utter the 'unsafe' notation.
I'm not sure I have an opinion as strong as pcwalton here, but I do think that you can't call yourself memory safe (even on a particular dimension) if you have to delineate all of the various language features that are unsafe without having to somehow explicitly annotate it as such in the source. Or at the very least, I don't think you can say that Zig's spatial memory safety is on even footing with Rust's (assuming pcwalton's characterization of Zig's unsafe features is correct).
The annotation really is the point here, because you can pin everything (modulo bugs and OS features that permit subversion) with regard to memory safety down to an unsafe annotation somewhere. That's a powerful tool that crystalizes what it means to be a "safe API."
As I said, I don't necessarily share pcwalton's strong opinion (although I do weakly agree with him) that having an annotation like 'unsafe' is the only way to go. I do think it's possible to go the Zig route and reduce memory safety bugs. But we should be very clear eyed about the claims being made and how comparisons are drawn.
- azakai 4y agoI don't think the annotation itself is actually the point. The point is being able to find all sources of unsafety and reason about them. Annotations do that, but other things can too. Imagine if you could run a tool on a codebase, and it statically found all the unsafe locations, and in idiomatic code there were very few of those, and you could reason about them. That would be equivalent to writing "unsafe" in the code, except you need to run the tool to "see" the annotations. That would be as good as annotations - it could prevent the same number of bugs. (Though I guess an argument could be, maybe some people forget to run the tool; fair enough.) No such tool can exist for C or C++. But such a tool could exist for a new language like Zig and Carbon, if they design themselves in certain ways, at least for spatial memory safety. Concretely, unsafe things like raw pointers in Zig have different types than safe slices, so a tool can actually find them; and unsafe things are (AFAIK) not idiomatic either, so they'd be rare.
- burntsushi 4y agoI think we'll just have to agree to disagree. I'm not certain you're wrong, so we'll have to see how it shakes out. And I love what the Zig project is doing, so I wouldn't at all be surprised if they find some other way here that works well in practice. Otherwise, I do think you underestimate the differences between an annotation like 'unsafe' and what you can find easily only through a static analysis tool. The key bit of the 'unsafe' annotation is the concept of "safe API" that it inspires, and also gives one a vocabulary for talking about things like 'soundness.' For example, you can mark Rust functions as 'unsafe' and then document the preconditions for avoiding UB. If you didn't mark that function as 'unsafe', then we would call it unsound because there exists an input that could cause UB, but it does not necessarily result in UB for every input. The annotation gives people a way to talk about and crystalize precisely what it means for an API to be safe for all uses. It funnels everything about memory safety down into that one concept and makes reasoning about it much much easier. Without an annotation like that, it's cumbersome or downright difficult to even talk or communicate about soundness.