How Safe Is Zig?

This page summarizes the projects mentioned and recommended in the original post on news.ycombinator.com

Our great sponsors
  • WorkOS - The modern identity platform for B2B SaaS
  • InfluxDB - Power Real-Time Data Analytics at Scale
  • SaaSHub - Software Alternatives and Reviews
  • sanitizers

    AddressSanitizer, ThreadSanitizer, MemorySanitizer

  • plotters

    A rust drawing library for high quality data plotting for both WASM and native, statically and realtimely 🦀 📈🚀

  • > You can write very simple Rust

    Technically true, but only really true if you don't use many dependencies. At some point you're going to use some dependency that uses async/await all over the place or really goes wild with generics and then it is definitely not simple.

    Two examples:

    * Heim (https://docs.rs/heim/0.0.11/heim/) is a great crate for getting system info, but it only uses async/await so you are thrown into that rather painful world even if you don't need it.

    * Plotters (https://github.com/38/plotters) is a pretty great graph plotting library for Rust (the only one as far as I know), but they have definitely gone a bit overboard with the generics. Want to draw a scatter graph?

    I tried simply calling `PointSeries::new()` and got a basically impossible-to-follow error about Rust not being able to infer the type `E` here:

    https://github.com/38/plotters/blob/master/src/series/point_...

    Very simple it is not!

  • WorkOS

    The modern identity platform for B2B SaaS. The APIs are flexible and easy-to-use, supporting authentication, user identity, and complex enterprise features like SSO and SCIM provisioning.

    WorkOS logo
  • materialize

    The data warehouse for operational workloads. (by MaterializeInc)

  • > I don't think I understand what is meant by "type confusion".

    Accessing a memory location with one type as if it's another. In C or C++ it's usually because you accessed a union without checking a tag somewhere else.

    One classic way this happens is in an interpreter where you have a big enum for all the different possible data types:

    https://github.com/MaterializeInc/materialize/blob/1b9b3cfab...

    And then in various builtin functions you expect particular types:

    https://github.com/MaterializeInc/materialize/blob/main/src/...

    In rust and zig this code will produce a runtime error if you screw up, but in c it's easy to forget to check the tag and then you get UB.

    Of course rust and zig both have support for c-style unions too, but they're not the first thing people reach for.

  • zig

    General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.

  • The word "none" in this blog post is misleading, for the rows use after free, double free, and uninitialized memory. Criticism is of course welcome but let's make sure we get all the facts on the table so we're not arguing a straw man.

    Copied here [from lobsters](https://lobste.rs/s/v5y4jb/how_safe_is_zig#c_vddk9j):

    With regards to use after free and double free, this is solved in practice for heap allocations. The basic building block of heap allocation, page_allocator, uses a global, atomic, monotonically increasing address hint to mmap, ensuring that virtual address pages are not reused until the entire virtual address space has been exhausted. In practice, this is a very long time for 64-bit applications. The standard library GeneralPurposeAllocator in safe build modes follows a similar strategy for large allocations and for small allocations, does not re-use slots. Similarly, an ArenaAllocator backed by page_allocator does not re-use any virtual addresses.

    This covers all the use cases of heap allocation, and so I think it’s worth making the safety table a bit more detailed to take this scenario into account. Additionally, as far as stack allocations go, there is a plan to do escape analysis and add this (optional) safety for stack allocations as well.

    As far as initialized memory goes, zig forces you to initialize all variable declarations. So an uninitialized memory has the word undefined in it. And in safe build modes, this writes 0xaa bytes to the memory. This is not enough to be considered “safe” but I think it’s enough that the word “none” is not quite correct.

    As for data races, this is an area where Rust completely crushes Zig in terms of safety, hands down.

    I do want to note that the safety story in zig is [under active development](https://github.com/ziglang/zig/projects/3) and will be worth checking back in on in a year or two and see what has changed :)

NOTE: The number of mentions on this list indicates mentions on common posts plus user suggested alternatives. Hence, a higher number means a more popular project.

Suggest a related project

Related posts