comprehensive-rust
comprehensive-rust copied to clipboard
Fix raw pointer example which has UB
The raw pointer example looks safe, but Miri flags it as having undefined behavior. This is a followup to the discussion in #177.
If triggers undefined behaviour then we shouldn't have it as an example, but I'm not clear on why it is UB.
The two-phase borrows mechanic means that r1 is considered inactive until it's used to write through, and that write pops r2 off the borrow stack.
The two-phase borrows mechanic means that
r1is considered inactive until it's used to write through, and that write popsr2off the borrow stack.
Thanks @riking!
@qwandor, I would like to merge this so we can warn people against the example. The other examples in this section are similarly full of things not to do, so it fits into the theme.
Hi @gendx, I think you've played a lot with unsafe... can you review this? Thanks :smile:
We should write an example that is valid instead.
How about something like this:
fn main() {
let mut array = [5, 6];
let r1 = &mut array[0] as *mut i32;
let r2 = &array[1] as *const i32;
unsafe {
println!("r1 is: {}", *r1);
*r1 = 10;
println!("r1 is: {}", *r1);
println!("r2 is: {}", *r2);
}
println!("array is: {array:?}");
}
Miri looks happy about it.
Bonus code to modify if you want to get to Miri:
fn main() {
let mut array = [5, 6];
let r1 = &mut array[0] as *mut i32;
let r2 = &array[1] as *const i32;
unsafe {
println!("r1 is: {}", *r1);
*r1 = 10;
println!("r1 is: {}", *r1);
// Undefined behavior because this breaks the aliasing rules, as
// r1.offset(1) and r2 are aliasing the same memory.
//*r1.offset(1) = 20;
println!("r2 is: {}", *r2);
}
println!("array is: {array:?}");
}
How about #486 instead?