@@ -135,11 +135,24 @@ to compute the address of array index `idx`. This relies on
135
135
how arrays are laid out in memory.
136
136
* For a struct, however, in general we do not know how it is laid out, and we
137
137
also cannot use ` &mut base_ptr.field ` as that would be creating a
138
- reference. Thus, it is currently not possible to create a raw pointer to a field
139
- of a partially initialized struct, and also not possible to initialize a single
140
- field of a partially initialized struct. (a
141
- [ solution to this problem] ( https://github.com/rust-lang/rust/issues/64490 ) is being
142
- worked on).
138
+ reference. So, you must carefully use the [ ` addr_of_mut ` ] macro. This creates
139
+ a raw pointer to the field without creating an intermediate reference:
140
+
141
+ ``` rust
142
+ use std :: {ptr, mem :: MaybeUninit };
143
+
144
+ struct Demo {
145
+ field : bool ,
146
+ }
147
+
148
+ let mut uninit = MaybeUninit :: <Demo >:: uninit ();
149
+ // `&uninit.as_mut().field` would create a reference to an uninitialized `bool`,
150
+ // and thus be Undefined Behavior!
151
+ let f1_ptr = unsafe { ptr :: addr_of_mut! ((* uninit . as_mut_ptr ()). field) };
152
+ unsafe { f1_ptr . write (true ); }
153
+
154
+ let init = unsafe { uninit . assume_init () };
155
+ ```
143
156
144
157
One last remark: when reading old Rust code, you might stumble upon the
145
158
deprecated ` mem::uninitialized ` function. That function used to be the only way
@@ -155,6 +168,7 @@ it around at all, be sure to be *really* careful.
155
168
[ `MaybeUninit` ] : ../core/mem/union.MaybeUninit.html
156
169
[ assume_init ] : ../core/mem/union.MaybeUninit.html#method.assume_init
157
170
[ `ptr` ] : ../core/ptr/index.html
171
+ [ `addr_of_mut` ] : ../core/ptr/macro.addr_of_mut.html
158
172
[ `write` ] : ../core/ptr/fn.write.html
159
173
[ `copy` ] : ../std/ptr/fn.copy.html
160
174
[ `copy_nonoverlapping` ] : ../std/ptr/fn.copy_nonoverlapping.html
0 commit comments