Live data from Hacker News

Unsafe Zig Is Safer Than Unsafe Rust

andrewkelley.me

1–10 of 105 posts

Re: Unsafe Zig Is Safer Than Unsafe Rust

#2
Transmute is like, the most unsafe thing possible. It basically checks if the two things have the same size, and that's it. You're responsible for everything else.

See all the warnings and suggested other ways to accomplish things with https://doc.rust-lang.org/stable/std/mem/fn.transmute.html

This is UB becuase `Foo` is not `#[repr(C)]`, in my understanding. I haven't checked if it works if you add the repr though. I don't think I'd expect it to.

Re: Unsafe Zig Is Safer Than Unsafe Rust

#3
Rust is a language that offers you lots of compile time checks, and an escape hatch called unsafe that says “trust the programmer here.” Yes, it is possible—and easy—to make mistakes in the place where you have asked to be trusted, not checked.

We have a big pedagogical task ahead of us in teaching safe practices for unsafe Rust, and defensive coding practices in unsafe Rust.

We should also think of if we can improve unsafe Rust to be harder to misuse. There are improvements coming in compile time evaluation, and those can potentially make the compiler much stronger when it comes to detecting memory errors in unsafe code at compile time.

Re: Unsafe Zig Is Safer Than Unsafe Rust

#4
post #3

Rust is a language that offers you lots of compile time checks, and an escape hatch called unsafe that says “trust the programmer here.” Yes, it is possible—and easy—to make mistakes in the place where you have asked to be trusted, not checked. We have a big pedagogical task ahead of us in teaching safe practices for unsafe Rust, and defensive coding practices in unsafe Rust. We should also think of if we can improve…

It will be interesting to watch the proportion of safe/unsafe code in large Rust codebases over time.

Re: Unsafe Zig Is Safer Than Unsafe Rust

#5

Transmute is like, the most unsafe thing possible. It basically checks if the two things have the same size, and that's it. You're responsible for everything else. See all the warnings and suggested other ways to accomplish things with https://doc.rust-lang.org/stable/std/mem/fn.transmute.html This is UB becuase `Foo` is not `#[repr(C)]`, in my understanding. I haven't checked if it works if you add the repr though.…

I changed it to:

        let foo = &mut array[0] as *mut u8 as *mut Foo;
        (*foo).a += 1;
and the IR has the same undefined behavior: https://godbolt.org/g/5Bv3FL

Re: Unsafe Zig Is Safer Than Unsafe Rust

#6

Transmute is like, the most unsafe thing possible. It basically checks if the two things have the same size, and that's it. You're responsible for everything else. See all the warnings and suggested other ways to accomplish things with https://doc.rust-lang.org/stable/std/mem/fn.transmute.html This is UB becuase `Foo` is not `#[repr(C)]`, in my understanding. I haven't checked if it works if you add the repr though.…

I changed it to: let foo = &mut array[0] as *mut u8 as *mut Foo; (*foo).a += 1; and the IR has the same undefined behavior: https://godbolt.org/g/5Bv3FL

Yeah I mean, to be clear, it's cool zig checks this stuff. Unsafe code is extremely dangerous, in a variety of ways.

Luckily, outside of FFI, it's very rare to actually need to write it, though that does of course depend on what exactly you're doing.

We hope, in the future, to basically have tooling here that can detect when you do something UB, and warn you. As we're still sorting out the memory model, etc, it's not here yet, but it's certainly on the agenda.

Re: Unsafe Zig Is Safer Than Unsafe Rust

#7

Transmute is like, the most unsafe thing possible. It basically checks if the two things have the same size, and that's it. You're responsible for everything else. See all the warnings and suggested other ways to accomplish things with https://doc.rust-lang.org/stable/std/mem/fn.transmute.html This is UB becuase `Foo` is not `#[repr(C)]`, in my understanding. I haven't checked if it works if you add the repr though.…

Wouldn't you need to make `Foo` a union for this to be defined anyway?

Re: Unsafe Zig Is Safer Than Unsafe Rust

#8
post #7

Transmute is like, the most unsafe thing possible. It basically checks if the two things have the same size, and that's it. You're responsible for everything else. See all the warnings and suggested other ways to accomplish things with https://doc.rust-lang.org/stable/std/mem/fn.transmute.html This is UB becuase `Foo` is not `#[repr(C)]`, in my understanding. I haven't checked if it works if you add the repr though.…

Wouldn't you need to make `Foo` a union for this to be defined anyway?

Rust `#[repr(C)]` is about representation in memory and function call ABI for the type. C rules about casting through union are not relevant to Rust code.

Re: Unsafe Zig Is Safer Than Unsafe Rust

#9
post #3

Rust is a language that offers you lots of compile time checks, and an escape hatch called unsafe that says “trust the programmer here.” Yes, it is possible—and easy—to make mistakes in the place where you have asked to be trusted, not checked. We have a big pedagogical task ahead of us in teaching safe practices for unsafe Rust, and defensive coding practices in unsafe Rust. We should also think of if we can improve…

There's not only a pedagogical task here, but the Rust community must learn how to write code safely. The major difficulty here is that in general, unsafe pieces of code cannot be safely composed, even if the unsafe pieces of code are individually safe. This allows you to bypass runtime safety checks without unsafe code just by composing "safe" modules that internally use unsafe code in their implementation.

This kind of problem comes up a lot. Composed atomic operations are not atomic. Composed correct threaded code is not always correct. Mixing Scheme control structures made with call/cc don't work as desired. Enabling different Haskell language extensions gets you off the deep end quickly, and some unsafe combinations are surprising (see GeneralizedNewtypeDeriving, which is considered unsafe even though it used to be safe).

Re: Unsafe Zig Is Safer Than Unsafe Rust

#10

Transmute is like, the most unsafe thing possible. It basically checks if the two things have the same size, and that's it. You're responsible for everything else. See all the warnings and suggested other ways to accomplish things with https://doc.rust-lang.org/stable/std/mem/fn.transmute.html This is UB becuase `Foo` is not `#[repr(C)]`, in my understanding. I haven't checked if it works if you add the repr though.…

> Transmute is like, the most unsafe thing possible.

Yes, the first rule of auditing Rust unsafe blocks is that if you see someone using std::mem::transmute, you walk over and ask the author if they're really certain what they're doing. :) However, it should be noted that std::mem::transmute still has some guard rails; the real "most unsafe thing possible" is the variant of this function that does away with those guard rails: std::mem::transmute_copy.

Required reading: https://doc.rust-lang.org/nightly/nomicon/transmutes.html

Post reply on HN