@@ -215,16 +215,12 @@ Values
215215 let u = U { x: 255 }; // 255 is not a valid bool representation
216216 let b = unsafe { u.b }; // UB — invalid bool
217217
218- .. compliant_example ::
219- :id: compl_ex_Ke869nSXuShT
218+ .. non_compliant_example ::
219+ :id: non_compl_ex_Qb5GqYTP6db4
220220 :status: draft
221221
222- In this compliant example, ``s `` contains uninitialized padding and ``copy_of_s `` contains a copy of those uninitialized padding bytes.
223- Both values are fully valid as long as only their fields are read.
224- ``#[derive(Copy, Clone)] `` allows ``S `` to be bitwise copied.
225- Bitwise copying does not read the padding, it just copies whatever bytes are present.
226- Uninitialized bytes can be copied (including padding).
227- Reading padding is undefined behavior, but copying it is not.
222+ This noncompliant example has undefined behavior when ``assume_init() `` is called on ``tmp `` because
223+ not all the fields of ``struct S `` have been initialized.
228224
229225 .. code-block :: rust
230226
@@ -242,17 +238,44 @@ Values
242238
243239 unsafe {
244240 (*tmp.as_mut_ptr()).a = a;
245- tmp.assume_init()
241+ tmp.assume_init() // Error: UB
246242 }
247243 }
248244
249245 fn main() {
250246 let s = make_s(10);
251- println!("s.a = {}", s.a); // OK
252- println!("s.b = {}", s.b); // Error: UB
247+ println!("s.a = {}, s.b = {} ", s.a, s.b);
248+ }
253249
254- let copy_of_s = s; // OK
255- println!("copy_of_s.a = {}", copy_of_s.a); // OK
256- println!("copy_of_s.b = {}", copy_of_s.b); // Error: UB
250+ .. compliant_example ::
251+ :id: compl_ex_Ke869nSXuShT
252+ :status: draft
253+
254+ This compliant example example is free from undefined behavior, even though the three bytes of padding between ``s.a `` and ``s.b `` is uninitialized.
255+ Padding bytes do not need to be initialized.
256+
257+ .. code-block :: rust
258+
259+ use std::mem::MaybeUninit;
260+
261+ #[repr(C)]
262+ #[derive(Copy, Clone)]
263+ struct S {
264+ a: u8,
265+ b: u32,
266+ }
267+
268+ fn make_s(a: u8, b: u32) -> S {
269+ let mut tmp = MaybeUninit::<S>::uninit();
270+
271+ unsafe {
272+ (*tmp.as_mut_ptr()).a = a;
273+ (*tmp.as_mut_ptr()).b = b;
274+ tmp.assume_init()
275+ }
257276 }
258277
278+ fn main() {
279+ let s = make_s(10, 42);
280+ println!("s.a = {}, s.b = {}", s.a, s.b);
281+ }
0 commit comments