How to get a pointer to a containing struct from a pointer to a member?
pointers, rust
Solution
The dereference expression produces an lvalue, but that lvalue is not actually read from, we're just doing pointer math on it, so in theory, it should be well defined. That's just my interpretation though.
My solution involves using a null pointer to retrieve the offset to the field, so it's a bit simpler than yours as it avoids one subtraction (we'd be subtracting 0). I believe I saw some C compilers/standard libraries implementing `offsetof` by essentially returning the address of a field from a null pointer, which is what inspired the following solution.
fn main() {
let p: *const Baz = 0x1248 as *const _;
let p2: *const Foo = unsafe { ((p as usize) - (&(*(0 as *const Foo)).memberB as *const _ as usize)) as *const _ };
println!("{:p}", p2);
}
We can also define our own `offset_of!` macro:
macro_rules! offset_of {
($ty:ty, $field:ident) => {
unsafe { &(*(0 as *const $ty)).$field as *const _ as usize }
}
}
fn main() {
let p: *const Baz = 0x1248 as *const _;
let p2: *const Foo = ((p as usize) - offset_of!(Foo, memberB)) as *const _;
println!("{:p}", p2);
}
Problem
I have a type: ``` struct Foo { memberA: Bar, memberB: Baz, } ``` and a pointer which I know is a pointer to `memberB` in `Foo`: ``` p: *const Baz ``` What is the correct way to get a new pointer `p: *const Foo` which points to the original struct `Foo`? My current implementation is the following, which I'm pretty sure invokes undefined behavior due to the dereference of `(p as *const Foo)` where `p` is not a pointer to a `Foo`: ``` let p2 = p as usize - ((&(*(p as *const Foo)).memberB as *const _ as usize) - (p as usize)); ``` This is part of FFI - I can't easily restructure the code to avoid needing to perform this operation. This is very similar to Get pointer to object from pointer to some member but for Rust, which as far as I know has no `offsetof` macro.