FWIW, although ::memoffset
is currently the best effort to get the offset for #[repr(C)]
struct
s that come from external crates, its implementation is technically UB, so if the definition comes from your own crate, you should take advantage of that to get offsets without unsafe
and thus without UB:
#![forbid(unsafe_code)]
// ...
with_offsets! {
#[repr(C)]
pub
struct Example {
#[offset(FOO_OFFSET)]
foo: u32,
#[offset(BAR_OFFSET)]
bar: usize,
}
}
fn main ()
{
dbg!(Example::BAR_OFFSET); // outputs 8 on the Playground
}
which, with #[macro_rules_attribute]
, leads to:
#[macro_use]
extern crate macro_rules_attribute;
#[macro_rules_attribute(with_offsets!)]
#[repr(C)]
pub
struct Example {
#[offset(FOO_OFFSET)]
foo: u32,
#[offset(BAR_OFFSET)]
bar: usize,
}
EDIT: and here is a version not requiring special identifiers for the constants:
#![forbid(unsafe_code)]
// ...
with_offsets! {
#[repr(C)]
pub
struct Example {
foo: u32,
_pad: u8,
baz: u8,
bar: u64,
}
}
fn main ()
{
assert_eq!(0, dbg!(Example::offset_to.foo));
assert_eq!(5, dbg!(Example::offset_to.baz));
assert_eq!(8, dbg!(Example::offset_to.bar));
}