// run-pass #![feature(const_ptr_sub_ptr)] #![feature(ptr_sub_ptr)] struct Struct { field: (), } #[repr(C)] struct Struct2 { data: u8, field: u8, } pub const OFFSET: usize = { let uninit = std::mem::MaybeUninit::::uninit(); let base_ptr: *const Struct = &uninit as *const _ as *const Struct; // The following statement is UB (taking the address of an uninitialized field). // Const eval doesn't detect this right now, but it may stop compiling at some point // in the future. let field_ptr = unsafe { &(*base_ptr).field as *const () as *const u8 }; let offset = unsafe { field_ptr.offset_from(base_ptr as *const u8) }; offset as usize }; pub const OFFSET_2: usize = { let uninit = std::mem::MaybeUninit::::uninit(); let base_ptr: *const Struct2 = &uninit as *const _ as *const Struct2; let field_ptr = unsafe { &(*base_ptr).field as *const u8 }; let offset = unsafe { field_ptr.offset_from(base_ptr as *const u8) }; offset as usize }; pub const OVERFLOW: isize = { let uninit = std::mem::MaybeUninit::::uninit(); let base_ptr: *const Struct2 = &uninit as *const _ as *const Struct2; let field_ptr = unsafe { &(*base_ptr).field as *const u8 }; unsafe { (base_ptr as *const u8).offset_from(field_ptr) } }; pub const OFFSET_EQUAL_INTS: isize = { let ptr = 1 as *const u8; unsafe { ptr.offset_from(ptr) } }; pub const OFFSET_UNSIGNED: usize = { let a = ['a', 'b', 'c']; let ptr = a.as_ptr(); unsafe { ptr.add(2).sub_ptr(ptr) } }; fn main() { assert_eq!(OFFSET, 0); assert_eq!(OFFSET_2, 1); assert_eq!(OVERFLOW, -1); assert_eq!(OFFSET_EQUAL_INTS, 0); assert_eq!(OFFSET_UNSIGNED, 2); }