These two methods seem to do almost the same thing except that one is safe and not the other.
From a C programmer's perspective, offset arithmetic on a pointer is as simple as an add/sub operation on usize type.
So, why rust has two distinct offset
methods? What is the concern?
The statement below comes from the doc of ptr::wrapping_offset()
:
The resulting pointer “remembers” the allocated object that self points to; it must not be used to read or write other allocated objects.
In other words, let z = x.wrapping_add((y as usize) - (x as usize)) does not make z the same as y even if we assume T has size 1 and there is no overflow: z is still attached to the object x is attached to, and dereferencing it is Undefined Behavior unless x and y point into the same allocated object.
`The statement, "let z = x.wrapping_add((y as usize) - (x as usize)) does not make z the same as y even if we assume T has size 1 and there is no overflow", confused me a lot.
I have written a simple toy program for testing:
fn main() {
let s: &str = "123456789";
let x: *const u8 = s.as_ptr();
let y: *const u8 = (s.as_ptr() as usize + 4) as *const u8;
let off: isize = (y as isize) - (x as isize);
println!("off {:?}", off);
let z = x.wrapping_offset(off);
println!("x {:p}, y {:p}, z {:p}", x, y, z);
}
Output:
off 4
x 0x102ff6920, y 0x102ff6924, z 0x102ff6924
This tells me that z
now points to the same address as z
points to. What does "z is still attached to the object x is attached to" mean?