| I'm confused when people preach Zig and then safety in the same sentence. Zig has basically all the same problems that C++ has with a few extra bells and whistles. There are perfectly good reasons to like Zig, but it being "safe" is not one of them. > For example, this comes through in little things like Zig's extreme simplicity and explicitness "Simplicity" does not mean safety. In fact simplicity means you can't describe hard problems easily without being overly verbose, which means more code and more attack surfaces. Problems are what can be simple or complex. If your language advertises "simplicity" it just means it can't solve complex problems in straight forward ways. Zig is just repeating the mistakes of C++ as well as all the mistakes of Go. > or people who haven't worked in security, integer overflow and wraparound may seem like a small thing, but they increase the probability of buffer bleeds, i.e. attacks like OpenSSL's Heartbleed, which are often remotely accessible and easier to pull off than a UAF. Zig does exactly what Rust does in this case. > In fact, no language is 100% memory safe, i.e. able to prevent a memory buffer bleed, because these are logic errors with respect to the file or protocol format. What are you trying to argue here? Buffer bleeds can't happen in safe rust. > The borrow checker is obviously great for multithreaded systems, but if you're using io_uring for fast I/O, then multithreading is less of the necessary evil that it used to be a few years ago. Syncronization is a problem in any kind of multitasking. Whether that happens inside or outside the language is the only question. The OS can have all the same problems your code can have. https://mobile.twitter.com/axboe/status/1505335772706091011 Also io_uring assumes you're only ever writing for Linux. > Nevertheless, Zig is safer than Rust when it comes to checked arithmetic or being able to handle memory allocation failure. This is simply incorrect. Most of the problem with unchecked overflow is for buffer overflows, which are fully caught. Rust gives options to handle memory allocation failure if you want to handle it. Generally though for most applications simply crashing is completely fine. |
Thanks, I've tried to clarify that Zig provides spatial memory safety but not temporal memory safety, so hopefully it's less confusing.
> "Simplicity" does not mean safety.
Ceteris parabus, complexity breeds bugs and simplicity improves the probability of safety. For example, if I were auditing a piece of code for security, I would prefer the simplest correct program to the most complex correct program. Reduced surface area means reduced area for attack.
When I say that Zig pursues simplicity, I also mean this as high praise, that Zig is highly "orthogonal". In other words, able to solve difficult problems with a minimum of overlapping features. For example, Zig's comptime gives you generics, but also gives you so much more, plus there is also type safety throughout Zig's comptime, yet it eliminates the need for macros, and is more versatile, powerful and flexible at the same time. It's incredibly elegant. Nothing left to add, nothing left to take away.
> Zig does exactly what Rust does in this case.
Things like checked arithmetic matter and should be enabled by default in safe builds, yet Rust does not actually do this in safe release builds. Zig does and I hope that Rust one day will.
> What are you trying to argue here? Buffer bleeds can't happen in safe rust.
By definition, buffer bleeds can in fact happen in safe Rust. The borrow checker can protect against UAF and overflow, but the borrow checker can't protect against all kinds of underflow, which is what a buffer bleed is. You can even pull them off in JavaScript.
No language is actually 100% memory safe, not with respect to buffer bleeds.