Description
The case for it working:
I print the address. I then parse the formatted text, and convert the parsed integer into a pointer. I then dereference that constructed pointer. The constructed pointer is "derived from" the original pointer, so it should be valid.
The case for it not working:
Wow that's annoying. Plus, it'd be very nice to be able to implement e.g. tagged pointers in the obvious way, using future provenance-aware APIs, such as
unsafe fn tag<T: ? Sized>(ptr: *mut T, tag: u8) -> *mut T {
let addr: usize = ptr.addr();
debug_assert_eq!(addr & (tag as usize), 0);
ptr.with_addr(addr | (tag as usize))
}
Once we have provenance-aware APIs, it makes sense to allow manipulation of addresses without leaking provenance, as the developer has indicated that they intend to maintain the pointer provenance, not try to reconstruct it from just the address.
But what about all of the ptr as usize
in the standard library today? How much of it can avoid the ptrtoint, how much can potentially be ptr.addr()
in the future, and how much will need to be (the moral equivalent of a) ptr::leak
to maintain compatibility with today's semantics?
Printing the address of a pointer is the obvious example of a ptrtoint which does not necessarily lead to a inttoptr. I don't actually know if any other obscure ways to effectively get ptrtoint without writing ptr as usize
exist in the standard library.