← Back to context

Comment by vlovich123

6 hours ago

Zig makes you choose either safe or fast, not both. With Rust you can get both (generally).

Part of the safety you get with Rust is runtime bounds checking, which is equivalent to Zig in "safe" mode.

  • Bounds checking is like 1% of the safety that Rust guarantees you. That's a false-equivalence. The bigger ones are around memory safety like use-after-free, double-free, and memory issues in the face of concurrency. Zig does not help you with that.

  • There are many ways to get rid of bounds checking in Rust. One of those ways is just utilizing iterators. For alternatives, there's a bounds check cookbook you should checkout [0].

    Thus far, I've written two libraries that utilize Rust, and they are usually associated with "high performance". I was able to exceed the performance of similar libraries written in C/C++.

    To be perfectly clear, this doesn't mean Rust can replace C/C++ in every scenario, but the actual perf gap is narrower than some folks may be willing to admit.

    [0] https://shnatsel.medium.com/how-to-avoid-bounds-checks-in-ru...

  • Bound checks, which are part of what you get with Rust, also exist in ReleaseSafe Zig, that is true. But if that is what you wanted to say, your statement is very confusing and also does not answer the GP. If you meant to say ReleaseSafe and Rust are equivalent, then this is just false. ReleaseSafe still has many UBs (most importantly use after free and double free), not to mention that Rust solves many problems at compile time and Zig only at runtime.

    • Sorry, I agree I was unclear and your restatement accurately reflects my intent. My biggest concern with Zig safety is that ReleaseFast turns asserts into assumptions, which is equivalent to injecting UB at every failed assert site. I doubt many users are aware of that "feature".

Zig makes you choose that at build time. You can use safe builds for development to catch bugs, and fast builds for release. You can even use safe builds in of the release, and optimize hot paths with fast builds.

In practice, projects written in Zig very much can choose both.

  • Still doesn't have a good answer for use after free, although the allocators on the last release might help into that regard.

That’s not entirely true. There’s a third choice. You can go the TigerBeetle route (TigerStyle). Zig is extremely well suited for software where you just avoid dynamic memory allocation all together. It’s extremely fast, very effective and arguably very safe. But not suitable for all applications obviously.

There’s also another caveat that there’s an effort to build in build time static memory safety checks in a way that’s more general than Rusts borrow checker, through a kind of plug in system rather than forced into the language. It’s not part of mainline Zig yet but this seems to be the direction Andrew wants to go.

https://github.com/ityonemo/clr