Is this article true in regards to how Unsafe Zig is safer than Unsafe Rust?

Somebody sent me an article that discusses how unsafe Zig is safter than unsafe Rust. Is this true.

I am kinda weak with programming so I don't quite understand much about the terminologies and as such so I don't know if this is true by any chance, that is why I am asking you guys.

You can run the example on the playground. It will compile without error.

However on that link you can go to the "Tools" menu and select "Miri". This is a tool that detects a lot of UB. It should indeed give an error that looks something like this:

error: Undefined Behavior: type validation failed: encountered an unaligned reference (required 4 byte alignment but found 2)

So using transmute can indeed be incredibly unsafe, as the article (and the documentation says).

I'm not too familiar with unsafe Zig but if it always checks alignment then it is safer in that regard. Rust's compiler doesn't do such a check. Miri does but that is a separate tool that runs the code in an environment that's specially designed to detect UB as it happens.


There is a discussion on r/rust 2 year ago:


Can I tell the compiler in my PC to use miri?

Depends what you mean by "true".

Is that specific zig function easier to use correctly than a rust function that explicitly says it's "incredibly unsafe" in its documentation, as well as specifically says not to use it for "Turning an &mut T into an &mut U" as the blog post does? Yes.

Does that really matter to me? No, because in Rust I'm almost always in safe code where I don't even need to think about it. And Rust safe code is always safe, not just safe in one of the three release profiles.

And of course Rust has its own helpful functions for dealing with alignment, like [T]::align_to -- which is unsafe because it allows reinterpreting the data as something different, which can be unsound. Conspicuously, the article doesn't say what would happen in Zig if you tried to do that same thing between, say, an array of doubles and a String -- the documentation doesn't mention it either, so I assume it's just checking alignment and that would (at best) blow up horribly when you use it.

And we're close to safe rust being able to handle these situations, which will clearly be safer than unsafe Rust and unsafe Zig.

TL/DR: The post has a clickbait title and attacks a strawman. I'd ignore it because of that, even though Zig's alignment-parameterized pointers are a nice feature.


I see that is petty good.

It is true in this specific case (transmute is a horrible footgun), but OTOH keep in mind that there is no such thing as Safe Zig. If you're able to write most of your program in safe Rust, then it should be safer overall.


It's true that transmute is a footgun, but IMO that argument distracts from the issue at hand, since transmute should not be used for pointer casts in the first place:

    unsafe {
        let mut array: [u8; 1024] = [1; 1024];
//      let foo = std::mem::transmute::<&mut u8, &mut Foo>(&mut array[0]);
        let foo = &mut *(array.as_mut_ptr() as *mut Foo);
        foo.a += 1;

This code has the same alignment bug as the original but does not use transmute. (Miri still catches it.)

1 Like

MIRI is used not when compiling the code, but when running it. Here are instructions for running tests under MIRI.

1 Like

FWIW, there is an effort to be able to make this kind of transformations not even "less unsafe", but actually completely non-unsafe where applicable, and when not applicable, be able to express the invariants that you promise to manually uphold.

This is the safe transmute working-group, in here is their RFC.

In the meantime, there are crates out there which help perform this kind of byte reinterpretation safely,


Exactly, and that is precisely the while point of the post. To take one instance of pretty much the most dangerous thing in Rust period and use it to give the appearance that Zig is safer.

Yeah, that's cool. :sunglasses:

1 Like

Yeah, that's what I meant by the post attacking a strawman.

I could imagine a version of the post titled "How Zig Helps Catch Alignment Mistakes" which compared to the rust code that uses pointer casts, and can imagine that being a great post -- as I said, Zig does have some nice features here. But that's not what the post is right now.