Skip to content

Instantly share code, notes, and snippets.

@resilar
Last active March 10, 2018 09:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save resilar/baefbfbf0d733c69d70970d829938875 to your computer and use it in GitHub Desktop.
Save resilar/baefbfbf0d733c69d70970d829938875 to your computer and use it in GitHub Desktop.
offset_of & container_of macros for Rust
#[derive(Debug)]
struct Foo {
p: u16,
q: u32,
}
macro_rules! offset_of {
($container:ty, $field:ident) => (unsafe {
&(*(0usize as *const $container)).$field as *const _ as usize
})
}
macro_rules! container_of {
($ptr:ident, $container:ty, $field:ident) => ({
(($ptr as usize) - offset_of!($container, $field)) as *const $container
})
}
fn main() {
let foo = Foo { p: 42, q: 1234 };
println!("{:?}", foo);
println!("foo: 0x{:x}", &foo as *const _ as usize);
println!("offsetof(p): {}", offset_of!(Foo, p));
println!("offsetof(q): {}", offset_of!(Foo, q));
let pfieldptr = &foo.p as *const _;
let pcontainerptr = container_of!(pfieldptr, Foo, p);
println!("pfieldptr: 0x{:x}", pfieldptr as usize);
println!("pcontainerptr: 0x{:x}", pcontainerptr as usize);
println!("foo.p: {:?}", unsafe { (*pcontainerptr).p });
let qfieldptr = &foo.q as *const _;
let qcontainerptr = container_of!(qfieldptr, Foo, q);
println!("qfieldptr: 0x{:x}", qfieldptr as usize);
println!("qcontainerptr: 0x{:x}", qcontainerptr as usize);
println!("foo.q: {:?}", unsafe { (*qcontainerptr).q });
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment