void Pointers
void * is translated as AnyPtr, a type-erased Ptr. to_any erases the
element type and reinterpret_cast recovers it:
char data[] = "hi";
void *vp = data;
char *cp = vp;
#![allow(unused)]
fn main() {
let data: Value<Box<[u8]>> = Rc::new(RefCell::new(Box::from(*b"hi\0")));
let vp: Value<AnyPtr> =
Rc::new(RefCell::new((data.as_pointer() as Ptr<u8>).to_any()));
let cp: Value<Ptr<u8>> =
Rc::new(RefCell::new((*vp.borrow()).reinterpret_cast::<u8>()));
}
reinterpret_cast returns the original pointer when the requested type matches
the erased one, and a byte-level view otherwise, because C
code commonly casts A * to void * and reads it back as B *.
The malloc family allocates and frees through AnyPtr, so the returned
pointer is cast to the requested type and cast back to free it:
int *p = malloc(sizeof(int));
*p = 42;
free(p);
#![allow(unused)]
fn main() {
// malloc_refcount(n) is
// Ptr::alloc_array(vec![0u8; n].into_boxed_slice()).to_any()
let p: Value<Ptr<i32>> = Rc::new(RefCell::new(
malloc_refcount(::std::mem::size_of::<i32>()).reinterpret_cast::<i32>(),
));
(*p.borrow()).write(42);
free_refcount((*p.borrow()).to_any());
}
AnyPtr also carries memcpy, memset, and memcmp, forwarding to the
Ptr<u8> versions from C Strings over the byte view of its
pointee.
Warning
Two
AnyPtrvalues are equal only when they were erased from the same pointer type and compare equal as that type. Avoid *obtained from aPtr<i32>and one obtained from aPtr<u8>into the same allocation compare unequal, where C would consider them the same address. This is set to be fixed by comparing through the byte view instead.
Casts between AnyPtr and integers use the same to_int and from_int as
Ptr<T>.