66Values
77======
88
9- .. guideline :: Do not create values from uninitialized memory except for union fields
9+ .. guideline :: Do not create values from uninitialized memory
1010 :id: gui_uyp3mCj77FS8
1111 :category: mandatory
1212 :status: draft
@@ -16,21 +16,11 @@ Values
1616 :scope: system
1717 :tags: undefined-behavior, unsafe
1818
19- A program shall not create a value of any type from uninitialized memory,
20- except when accessing a field of a union type,
21- where such reads are explicitly defined to be permitted even if the bytes of that field are uninitialized.
19+ A program shall not create a value of any non-``union `` type from uninitialized memory.
20+ Reading from a union is covered by a separate rule, "Do not read from union fields that may contain uninitialized bytes".
2221 It is prohibited to interpret uninitialized memory as a value of any Rust type such as a
2322 primitive, aggregate, reference, pointer, struct, enum, array, or tuple.
2423
25- **Exception: ** You can access a field of a union even when the backing bytes of that field are uninitialized provided that:
26-
27- - The resulting value has an unspecified but well-defined bit pattern.
28- - Interpreting that value must still comply with the requirements of the accessed type
29- (e.g., no invalid enum discriminants, no invalid pointer values, etc.).
30-
31- For example, reading an uninitialized u32 field of a union is allowed;
32- reading an uninitialized bool field is disallowed because not all bit patterns are valid.
33-
3424 .. rationale ::
3525 :id: rat_kjFRrhpS8Wu6
3626 :status: draft
@@ -43,10 +33,6 @@ Values
4333 - may create invalid pointer values, or
4434 - may produce values that violate type invariants.
4535
46- The sole exception is that unions work like C unions: any union field may be read, even if it was never written.
47- The resulting bytes must, however, form a valid representation for the field's type,
48- which is not guaranteed if the union contains arbitrary data.
49-
5036 .. non_compliant_example ::
5137 :id: non_compl_ex_Qb5GqYTP6db1
5238 :status: draft
@@ -62,25 +48,6 @@ Values
6248 let x: u32 = unsafe { MaybeUninit::uninit().assume_init() }; // UB
6349 # }
6450
65- .. compliant_example ::
66- :id: compl_ex_Ke869nSXuShU
67- :status: draft
68-
69- Types such as ``u8 ``, ``u16 ``, ``u32 ``, and ``i128 `` allow all possible bit patterns.
70- Provided the memory is initialized, there is no undefined behavior.
71-
72- .. rust-example ::
73-
74- union U {
75- n: u32,
76- bytes: [u8; 4],
77- }
78-
79- # fn main() {
80- let u = U { bytes: [0xFF, 0xEE, 0xDD, 0xCC] };
81- let n = unsafe { u.n }; // OK — all bit patterns valid for u32
82- # }
83-
8451 .. compliant_example ::
8552 :id: compl_ex_Ke869nSXuShV
8653 :status: draft
@@ -144,45 +111,6 @@ Values
144111 let a = unsafe { std::mem::transmute: :<_, [u8; 4]>(arr) }; // UB — not all elements initialized
145112 # }
146113
147- .. compliant_example ::
148- :id: compl_ex_Ke869nSXuShT
149- :status: draft
150-
151- The following code reads a union field:
152-
153- .. rust-example ::
154-
155- union U {
156- x: u32,
157- y: f32,
158- }
159-
160- # fn main() {
161- let u = U { x: 123 }; // write to one field
162- let f = unsafe { u.y }; // reading the other field is allowed
163- # }
164-
165- .. non_compliant_example ::
166- :id: non_compl_ex_Qb5GqYTP6db3
167- :status: draft
168-
169- Even though unions allow reads of any field, not all bit patterns are valid for a ``bool ``.
170- Unions do not relax type validity requirements.
171- Only the read itself is allowed;
172- the resulting bytes must still be a valid bool.
173-
174- .. rust-example ::
175-
176- union U {
177- b: bool,
178- x: u8,
179- }
180-
181- # fn main() {
182- let u = U { x: 255 }; // 255 is not a valid bool representation
183- let b = unsafe { u.b }; // UB — invalid bool
184- # }
185-
186114 .. compliant_example ::
187115 :id: compl_ex_Ke869nSXuShW
188116 :status: draft
0 commit comments