Hacker News new | ask | show | jobs
by steveklabnik 3075 days ago
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.

3 comments

> 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

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.

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.