7 ms·
> This is a huge advantage over C++ and Rust, because it makes it much harder for e.g. the intern to write code that repeatedly creates a vector or dynamically
by AsyncAwait 6y ago
> This is a huge advantage over C++ and Rust, because it makes it much harder for e.g. the intern to write code that repeatedly creates a vector or dynamically allocated string in a loop. Or to use something like std::unordered_map or std::deque that allocates wantonly.
True. On the other hand, Zig makes a deliberate decision not to bother itself with memory safety too much, so its a win some, loose some sort of situation.
- pron 6y ago> On the other hand, Zig makes a deliberate decision not to bother itself with memory safety too much This is not true. Zig places a strong emphasis on memory safety, it just does so in a way that's very different from either Java's or Rust's. I wrote more about this here: https://news.ycombinator.com/item?id=24293329 https://news.ycombinator.com/item?id=24293329
- littlestymaar 6y ago> It does so with runtime checks that are turned on in development and testing and turned off -- either globally or per code unit -- in production. This isn't “memory safety”, with this reasoning you could say “C is memory safe if you use ASAN during debug”: it is exactly equivalent except Zig checks are less powerful than the full suite of existing sanitizers for C, but it's enabled by default in debug mode, which is nice.
- pron 6y agoNo, this is full memory safety enforced through runtime checks. ASAN does not give you that. Zig has only arrays and slices with known sizes and no pointer arithmetic (unless you explicitly appeal to unsafe operations).
- littlestymaar 6y ago> full memory safety enforced through runtime checks [disabled in production] Which means you cannot guaranty your program doesn't exhibit memory unsafely unless you stumble upon it during testing. Yes there are fewer footguns in Zig[1] than in C (which is the opposite of C++), but dangling pointer dereferences, double free and race conditions will still be lurking in any reasonably-sized codebase. Calling it “memory-safe”, is dishonest. And I actually don't think it serves Zig. It's a clever language with tons of good ideas, no need to oversell it with misleading claims about memory safety. [1]: but still plenty of them https://ziglang.org/documentation/master/#Undefined-Behavior https://ziglang.org/documentation/master/#Undefined-Behavior
- pron 6y ago> Which means you cannot guaranty your program doesn't exhibit memory unsafely unless you stumble upon it during testing. Right, if you disable those checks. > Calling it “memory-safe”, is dishonest. The language is (or will be) memory safe, at least its safe parts -- C/C++ aren't. True, that safety can be disabled selectively. Yes, there can then be undefined behaviour if you disable that safety, but so can Rust when you disable safety selectively. The design is just different. Just remember that using a language with sound guarantees is no one's goal. The goal is to produce programs without bugs. Sound guarantees in the language is one approach toward that goal; there are others. Generally, guaranteeing that some set of bugs cannot happen does not necessarily guarantee fewer bugs overall; in fact the opposite might be true. Nobody knows if Zig's strong safety story yields to more correct programs that Rust's, but nobody knows the opposite, either. There are good arguments either way but little data. In any event, Zig is much safer than C, even with ASAN.
- littlestymaar 6y ago> The language is (or will be) memory safe. We've been going full cicle here, so I'm not interested in spending more time in this conversation.
- judofyr 6y ago> Calling it “memory-safe”, is dishonest. I'm not sure why we desperately need to classify languages into "memory-safe" or "not memory-safe". The fact is that all languages have various levels memory-safety (sun.misc.Unsafe anyone?) and I do think that Zig deserves recognization for addressing it heads on: - There's a separate ReleaseSafe optimization level which has all the optimizations, but remains safe. If you care about memory-safety (which most people do!) then this should be your default production build. - The documentation is very clear about what can cause undefined behavior in ReleaseFast. - You can override the safety-level (both ways!) for a single scope. If you have something performance critical that can't be expressed in safe Zig you can opt-in to potential undefined behavior. If you have something safety-critical you can opt-in for correctness even though the overall program is compiled with ReleaseFast.
- 6y ago
- rfoo 6y agoI thought after Intel MPX we can all agree "memory safety" in modern languages is more about temporal stuff (i.e. use-after-free, etc) than bounds check, but maybe I'm wrong. How does those runtime checks kill UAF?
- pron 6y ago> https://github.com/ziglang/zig/pull/5998 https://github.com/ziglang/zig/pull/5998 TBD :) But here's one way that's currently being tried: https://github.com/ziglang/zig/pull/5998 https://github.com/ziglang/zig/pull/5998
- littlestymaar 6y ago(Small copy past error here, you posted the same link twice.) Regarding https://github.com/ziglang/zig/pull/5998 https://github.com/ziglang/zig/pull/5998 here we're exactly in the realm of C, changing the allocator with a custom one with additional bookkeeping to check for memory management issues. But it tanks performances so you can't generally use it for production (and if you were in a situation were you'd do it anyway, you'd be better off with completely automatic memory management: AKA a GC).
- pron 6y agoNo, Zig is not in the realm of C. Zig gives you full memory safety that you can then selectively turn off. Why is it useful? For the same reason tests are useful even if they don't give you sound guarantees, and are still the primary way of achieving correctness, even in Haskell or Rust. C does not and cannot do this the same way as Zig does, because C cannot be made safe (well, it can, but that's a whole other can of worms) while Zig can. So you make Zig safe, test it, and then remove the guardrails from the performance-critical bits after you're satisfied with their correctness. Does it provide safety in the same manner Rust does? Absolutely not. Does it provide less correctness overall? Maybe, and maybe it provides more correctness, and maybe the same. It's hard to say without an empirical study. The problem is that sound guarantees often come at a cost -- for example, to language complexity and compilation speed -- that can have a negative effect on correctness.
- AsyncAwait 6y agoI meant a borrow checker, which I assumed was clear from what I was replying to. Yes, Zig does do runtime checks in dev builds and I did not mean to imply otherwise, I don't think the runtime checks provide the same set of benefits. Just so we're clear, I like Zig :-)
- pron 6y ago> I don't think the runtime checks provide the same set of benefits. Of course not, but that doesn't mean Zig is less effective at achieving correctness. It just does so in a different way -- it trades sound guarantees for less sound ones and a simpler language with a faster cycle. Is one better than the other? Hard to say. Only empirical study could settle that.
- fsociety 6y agoI’d argue it does mean it is less effective at achieving correctness but the trade-off made is the whole point of Zig. Simple language that is really a better C.
- pron 6y agoIt's hard to make a definitive argument one way or the other because the guarantees Rust makes come at a cost of compilation speed and language complexity that can have a negative effect on correctness. This question is impossible to answer without an empirical study. Unlike C, Zig is (or will be) memory safe, although its safety can be turned off, and often is -- after testing. Unlike C, it provides powerful abstraction capabilities similar to those of C++. The fact that it can do all that yet be very simple seems to suggest at first glance that it's "like C" but that's because we've never had a language like that before. Zig's simplicity is misleading. It turns out you can do a lot with a very simple language. We knew that to be true for high-level languages like Scheme, but Zig shows it's possible in low-level languages, too.
- AsyncAwait 6y ago> It's hard to make a definitive argument one way or the other because the guarantees Rust makes come at a cost of compilation speed I don't think this is actually true. The compiler is slow but not due to memory safety; the 'cargo check' command is rather quick and the compiler itself doesn't seem to spend a lot of time in the frontend, most of the time in spent in the backend, past the borrow checking phrase.