@@ -253,89 +253,21 @@ pub unsafe fn dropped<T>() -> T {
253
253
dropped_impl ( )
254
254
}
255
255
256
- /// Bypasses Rust's normal memory-initialization checks by pretending to
257
- /// produce a value of type T, while doing nothing at all.
256
+ /// Creates an uninitialized value.
258
257
///
259
- /// **This is incredibly dangerous, and should not be done lightly. Deeply
260
- /// consider initializing your memory with a default value instead.**
261
- ///
262
- /// This is useful for FFI functions and initializing arrays sometimes,
263
- /// but should generally be avoided.
264
- ///
265
- /// # Undefined Behaviour
266
- ///
267
- /// It is Undefined Behaviour to read uninitialized memory. Even just an
268
- /// uninitialized boolean. For instance, if you branch on the value of such
269
- /// a boolean your program may take one, both, or neither of the branches.
270
- ///
271
- /// Note that this often also includes *writing* to the uninitialized value.
272
- /// Rust believes the value is initialized, and will therefore try to Drop
273
- /// the uninitialized value and its fields if you try to overwrite the memory
274
- /// in a normal manner. The only way to safely initialize an arbitrary
275
- /// uninitialized value is with one of the `ptr` functions: `write`, `copy`, or
276
- /// `copy_nonoverlapping`. This isn't necessary if `T` is a primitive
277
- /// or otherwise only contains types that don't implement Drop.
258
+ /// Care must be taken when using this function, if the type `T` has a destructor and the value
259
+ /// falls out of scope (due to unwinding or returning) before being initialized, then the
260
+ /// destructor will run on uninitialized data, likely leading to crashes.
278
261
///
279
- /// If this value *does* need some kind of Drop, it must be initialized before
280
- /// it goes out of scope (and therefore would be dropped). Note that this
281
- /// includes a `panic` occurring and unwinding the stack suddenly.
262
+ /// This is useful for FFI functions sometimes, but should generally be avoided.
282
263
///
283
264
/// # Examples
284
265
///
285
- /// Here's how to safely initialize an array of `Vec`s.
286
- ///
287
266
/// ```
288
267
/// use std::mem;
289
- /// use std::ptr;
290
268
///
291
- /// // Only declare the array. This safely leaves it
292
- /// // uninitialized in a way that Rust will track for us.
293
- /// // However we can't initialize it element-by-element
294
- /// // safely, and we can't use the `[value; 1000]`
295
- /// // constructor because it only works with `Copy` data.
296
- /// let mut data: [Vec<u32>; 1000];
297
- ///
298
- /// unsafe {
299
- /// // So we need to do this to initialize it.
300
- /// data = mem::uninitialized();
301
- ///
302
- /// // DANGER ZONE: if anything panics or otherwise
303
- /// // incorrectly reads the array here, we will have
304
- /// // Undefined Behaviour.
305
- ///
306
- /// // It's ok to mutably iterate the data, since this
307
- /// // doesn't involve reading it at all.
308
- /// // (ptr and len are statically known for arrays)
309
- /// for elem in &mut data[..] {
310
- /// // *elem = Vec::new() would try to drop the
311
- /// // uninitialized memory at `elem` -- bad!
312
- /// //
313
- /// // Vec::new doesn't allocate or do really
314
- /// // anything. It's only safe to call here
315
- /// // because we know it won't panic.
316
- /// ptr::write(elem, Vec::new());
317
- /// }
318
- ///
319
- /// // SAFE ZONE: everything is initialized.
320
- /// }
321
- ///
322
- /// println!("{:?}", &data[0]);
269
+ /// let x: i32 = unsafe { mem::uninitialized() };
323
270
/// ```
324
- ///
325
- /// Hopefully this example emphasizes to you exactly how delicate
326
- /// and dangerous doing this is. Note that the `vec!` macro
327
- /// *does* let you initialize every element with a value that
328
- /// is only `Clone`, so the following is equivalent and vastly
329
- /// less dangerous, as long as you can live with an extra heap
330
- /// allocation:
331
- ///
332
- /// ```
333
- /// let data: Vec<Vec<u32>> = vec![Vec::new(); 1000];
334
- /// println!("{:?}", &data[0]);
335
- /// ```
336
- ///
337
- /// For large arrays this is probably advisable
338
- /// anyway to avoid blowing the stack.
339
271
#[ inline]
340
272
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
341
273
pub unsafe fn uninitialized < T > ( ) -> T {
0 commit comments