File tree Expand file tree Collapse file tree 1 file changed +22
-3
lines changed Expand file tree Collapse file tree 1 file changed +22
-3
lines changed Original file line number Diff line number Diff line change @@ -141,15 +141,34 @@ fn panic(_info: &PanicInfo) -> ! {
141
141
}
142
142
143
143
/// Calculates the offset of a field from the beginning of the struct it belongs to.
144
+ ///
145
+ /// # Example
146
+ ///
147
+ ///```
148
+ /// struct Test {
149
+ /// a: u64,
150
+ /// b: u32,
151
+ /// }
152
+ ///
153
+ /// fn test() {
154
+ /// // This prints `8`.
155
+ /// println!("{}", offset_of!(Test, b));
156
+ /// }
157
+ ///```
144
158
#[ macro_export]
145
159
macro_rules! offset_of {
146
160
( $type: ty, $( $f: tt) * ) => { {
147
161
let tmp = core:: mem:: MaybeUninit :: <$type>:: uninit( ) ;
148
- let ptr = tmp. as_ptr( ) ;
162
+ let outer = tmp. as_ptr( ) ;
163
+ // To avoid warnings when nesting `unsafe` blocks.
149
164
#[ allow( unused_unsafe) ]
150
- let dev = unsafe { core:: ptr:: addr_of!( ( * ptr) . $( $f) * ) as * const u8 } ;
165
+ // SAFETY: The pointer is valid and aligned, just not initialised; `addr_of` ensures that
166
+ // we don't actually dereference it (which would be UB).
167
+ let inner = unsafe { core:: ptr:: addr_of!( ( * outer) . $( $f) * ) } as * const u8 ;
168
+ // To avoid warnings when nesting `unsafe` blocks.
151
169
#[ allow( unused_unsafe) ]
152
- unsafe { dev. offset_from( ptr as * const u8 ) }
170
+ // SAFETY: The two pointers are within the same allocation block.
171
+ unsafe { inner. offset_from( outer as * const u8 ) }
153
172
} }
154
173
}
155
174
You can’t perform that action at this time.
0 commit comments