Miri accepts this code, which prints 42:
#[repr(C)]
struct X {
a: usize,
}
#[repr(C)]
struct Y {
a: usize,
b: usize,
}
fn main() {
unsafe {
let x = X { a: 42 };
let py = &raw const x as *const Y;
let Y { a, .. } = *py;
println!("{a}");
}
}
On the other hand, the reference defines a dangling pointer as follows:
A reference/pointer is “dangling” if not all of the bytes it points to are part of the same live allocation (so in particular they all have to be part of some allocation).
And mentions as undefined behavior:
Accessing (loading from or storing to) a place that is dangling
Clearly, py is dangling by this definition, and clearly, the line let Y { a, .. } = *py; loads from py. So according to the reference, this should be UB. The reference does not have any notion of a "partially dangling" pointer that it's okay to read part of. Who is right: the reference or miri?
Miri accepts this code, which prints
42:On the other hand, the reference defines a dangling pointer as follows:
And mentions as undefined behavior:
Clearly,
pyis dangling by this definition, and clearly, the linelet Y { a, .. } = *py;loads frompy. So according to the reference, this should be UB. The reference does not have any notion of a "partially dangling" pointer that it's okay to read part of. Who is right: the reference or miri?