4 ms·
> Rust has the same thing. In Rust all of those features are delineated by unsafe. For one, you can disable unsafe with a compiler switch; Zig has no such equi
by pcwalton 4y ago
> Rust has the same thing.
In Rust all of those features are delineated by unsafe. For one, you can disable unsafe with a compiler switch; Zig has no such equivalent feature.
Moreover, we shouldn't assume that Zig pointers are the only feature that breaks spatial memory safety. It was simply the first one I found after like 2 minutes of looking through the docs. After like 5 more minutes I found another: extern unions. Just now I found another: sentinel-terminated pointers, since you could delete the sentinel.
It feels a bit like these arguments are going like "Zig is spatially memory safe!" "Well, what about X?" "OK, other than X, Zig is spatially memory safe!" "What about Y?" "OK, other than X and Y, Zig is spatially memory safe!" At this point the burden of proof isn't on me anymore.
It's obvious that full spatial memory safety just isn't a design goal of Zig. It seems like Zig's goal is simply to add tools, like slices, that reduce memory errors. Which is the same goal that, for example, the C++ STL has. It's a great goal, but it shouldn't be confused with Rust's goal.
> [1]: Even disregarding the hard question over which of Zig or Rust make it easier to write correct programs, which could go either way; that sound memory safety is a better path to correctness than a balance of less soundness combined with simplicity is your opinion
It's my opinion in the same sense that it's my opinion that wearing seatbelts results in fewer deaths on the road. The idea that memory-safe programming languages improves real-world safety is backed up by decades of experience. Anyone arguing otherwise has a massive burden of proof. And the arguments I've seen by people arguing that you don't need temporal memory safety are weak. The idea that a simple language that doesn't have ironclad safety guarantees reduces errors over a more complex language with those guarantees sounds nice in theory, but it hasn't actually turned out that way in practice.
- azakai 4y ago> Moreover, we shouldn't assume that Zig pointers are the only feature that breaks spatial memory safety. It was simply the first one I found after like 2 minutes of looking through the docs. After like 5 more minutes I found another: extern unions. Just now I found another: sentinel-terminated pointers, since you could delete the sentinel. You're right on each of those points. But (AFAIK) all those types are explicitly there for C interop. When interfacing with C, yes, Zig will inherit much of C's unsafety. But the big picture is that 1. Idiomatic Zig should not use those things, and 2. Those things are (IIUC) mechanically-identifiable at the type level. A compiler flag could warn about them. You can check if a codebase uses them, and find out exactly where. No such thing is possible for C. Maybe you'd prefer that an unsafe block be required to be placed around each of them, but in the end that's a matter of notation. In theory, Zig could decide to mandate such explicit unsafe blocks, but C couldn't - there isn't a useful safe subset to delineated. I could be wrong, however. Possibly the Zig community will decide that say sentinel-terminated pointers are good to use in general (and not just for C interop). And maybe I've missed something and those types cannot be discovered mechanically for auditing purposes. If either of those is the case then I'd agree Zig lacks spatial memory safety. (Btw, you seem downvoted atm. Not me, of course - there's probably no one else I respect more on the topic of memory safety than you! - and it's disappointing that people downvote comments just because they disagree.)
- pcwalton 4y agoWell, let's turn this around. Is C++ spatially memory safe? C++20 has slices (ranges). They're bounds checked, via the .at() method. You can get the integer overflow semantics of Zig with "-fsanitize=signed-integer-overflow -fsanitize=unsigned-integer-overflow -fsanitize=float-cast-overflow". You could write a checker that enforces that only these features are used (in fact, this checker basically exists--ISO Core C++ Guidelines). I don't see any reason why modern C++ wouldn't be just as spatially memory safe as Zig is, if we're allowed to subset the language in ways more trivial than "disable the unsafe keyword". The main thing that distinguishes Zig at that point would be that it's a simpler language. That's true. But I don't actually think that makes for safer programs, empirically speaking--otherwise, C programs would be safer than C++ programs, and they generally aren't.
- azakai 4y agoYes, technically there might exist a subset of C++ as safe as idiomatic Zig. But in practice inertia and legacy code and lack of ergonomics etc. work against that subset of C++ becoming popular - does anyone constantly type .at()? Zig can do better, if it doesn't squander the opportunity. In other words, this isn't about theoretical subsets of a language. It's that there is an opportunity when designing a new language to use better defaults and have better idiomatic patterns. If Zig and Carbon do it properly, I think they can get to a place where they have practically no spatial memory errors in the real world. That is measurable, in principle, so we'll see how it plays out I suppose.
- burntsushi 4y agoI think it's worthwhile to point out that there are two threads of argument here. One is what it means to be spatially memory safe. Another is whether and how effective various mitigations are.
- pjmlp 4y agoInstead of typing .at() you do #define _ITERATOR_DEBUG_LEVEL 1, done now operator[]() does bounds checking as well.
- pron 4y ago> In Rust all of those features are delineated by unsafe. They're also delineated in Zig, just not with a single keyword. Extern unions, unknown-length arrays, and sentinel-terminated arrays are features, with clear syntax, used for C interop only. > It's obvious that full spatial memory safety just isn't a design goal of Zig. It's as much of a goal in Zig as it is in Rust; both allow circumventing it with clearly marked unsafe features. > Which is the same goal that, for example, the C++ STL has. It's a great goal, but it shouldn't be confused with Rust's goal. You're confusing means and end. No one's ultimate goal is having this feature or another. Both Zig and Rust have, as one primary goal, helping write correct software. They just try to achieve it in different ways. Why is that good? Because we have no idea what is the most effective way of achieving that goal, so we try different approaches. > It's my opinion in the same sense that it's my opinion that wearing seatbelts results in fewer deaths on the road. I don't think so, because seatbelts have few accident-related downsides, while a complex language has many. > Anyone arguing otherwise has a massive burden of proof. I'm not arguing against seatbelts. Anyone who claims that X leads to more correct programs than Y -- not by looking at this or that property, but as a whole -- has a massive burden of proof. I am not claiming Zig is more effective at writing correct programs than Rust. After years exploring issues in software correctness -- including with different formal methods -- my claim, which is closer to consensus than controversy, is that we simply don't know. We don't know which of Zig's or Rust's approaches leads to more software, and therefore we cannot say which of those approaches is preferable, even if correctness is the main thing we care about. > And the arguments I've seen by people arguing that you don't need temporal memory safety are weak. The idea that a simple language that doesn't have ironclad safety guarantees reduces errors over a more complex language with those guarantees sounds nice in theory, but it hasn't actually turned out that way in practice. We simply don't know either way. We might know that a language with ironclad guarantees leads to more correct software than C, but given that Zig is as different from C as Rust is -- and as different as they are to each other -- there's nothing that allows us to extrapolate. Your argument amounts to, "my way is the best way", and your evidence is irrelevant extrapolations. One could then ask, if Rust's design is so great, how come, at its not-so-young age -- which is quickly nearing the age at which all languages (with the possible exception of Python) have reached or approached their all-time peak popularity -- so few people use it? Could it be that there's no "room" for it? (I'm not saying that's the case at all -- I think Rust, like Zig, is a very interesting language.) Its low popularity certainly makes claims along the lines of, "the design of this language is obviously the only design for which there's room in 2022," ring quite hollow. There's no room for anything other than an approach whose success is so uncertain? Really? Given that Rust has proven quite the opposite of an overnight success, I think some humility about its design choices is appropriate.