Rust continues to top the charts as the most admired and desired language by developers, and in this post, we dive a little deeper into how (and why) Rust is stealing the hearts of developers around the world.
Unlike C++, Rust doesn’t allow mutable memory aliasing. That’s because mutable aliasing can never happen in Safe Rust, and not supporting it improves performance. This means that when writing Unsafe Rust, one has to be careful about aliasing.
Note though that it’s perfectly fine to have multiple mutable raw pointers pointing to the same data, as long as there’s no ownership held by any Rust code. The problem only happens if you try to convert them into references.
I left something important out from my explanation. Your example still holds ownership of the data, so that’s where the rules are violated with those raw pointers. You have to use Box::into_raw or something similar to disassociate the data from the Rust compiler. Then you can alias it using raw pointers.
@soulsource@anlumo dude your whole code is UB. A reference & means that the data behind it never changes while any reference exists, allowing multiple pointers to point at it at the same time (aliasing); whereas a mutable reference &mut means that the data behind may only be read or written by that pointer, i.e. multiple pointers (aliasing) can’t exist. The compiler uses this to optimize code and remove stuff that you promise never happens. Always use miri, and go read the nomicon.
Thanks for correcting my worldview, because after that playground behaved as it should if aliasing were allowed my worldview was kinda shattered. Oh, and I had completely forgotten that Playground has Miri built in.
Note though that it’s perfectly fine to have multiple mutable raw pointers pointing to the same data, as long as there’s no ownership held by any Rust code. The problem only happens if you try to convert them into references.
It seems I misunderstood something important here. I’d take that as proof that Unsafe Rust is rarely needed. 😜 A quick test on the Playground shows that indeed, using raw pointers does not yield the wrong result, while using references does: https://play.rust-lang.org/?version=stable&mode=release&edition=2021&gist=96f80d43d71a73018f23705d74b7e21d
Conclusion: Unsafe Rust is not as difficult as I thought.
I left something important out from my explanation. Your example still holds ownership of the data, so that’s where the rules are violated with those raw pointers. You have to use
Box::into_raw
or something similar to disassociate the data from the Rust compiler. Then you can alias it using raw pointers.@soulsource @anlumo dude your whole code is UB. A reference
&
means that the data behind it never changes while any reference exists, allowing multiple pointers to point at it at the same time (aliasing); whereas a mutable reference&mut
means that the data behind may only be read or written by that pointer, i.e. multiple pointers (aliasing) can’t exist. The compiler uses this to optimize code and remove stuff that you promise never happens. Always use miri, and go read the nomicon.That was how I thought it works until yesterday. And Miri seems to confirm what I thought.
But then there was this comment, that suggested otherwise: https://discuss.tchncs.de/comment/2544085
Thanks for correcting my worldview, because after that playground behaved as it should if aliasing were allowed my worldview was kinda shattered. Oh, and I had completely forgotten that Playground has Miri built in.