[−][src]Union std::mem::MaybeUninit
A newtype to construct uninitialized instances of T
.
The compiler, in general, assumes that variables are properly initialized at their respective type. For example, a variable of reference type must be aligned and non-NULL. This is an invariant that must always be upheld, even in unsafe code. As a consequence, zero-initializing a variable of reference type causes instantaneous undefined behavior, no matter whether that reference ever gets used to access memory:
#![feature(maybe_uninit)] use std::mem::{self, MaybeUninit}; let x: &i32 = unsafe { mem::zeroed() }; // undefined behavior! // equivalent code with `MaybeUninit` let x: &i32 = unsafe { MaybeUninit::zeroed().into_initialized() }; // undefined behavior!Run
This is exploited by the compiler for various optimizations, such as eliding
run-time checks and optimizing enum
layout.
Not initializing memory at all (instead of zero-initializing it) causes the same issue: after all, the initial value of the variable might just happen to be one that violates the invariant. Moreover, uninitialized memory is special in that the compiler knows that it does not have a fixed value. This makes it undefined behavior to have uninitialized data in a variable even if that variable has otherwise no restrictions about which values are valid:
#![feature(maybe_uninit)] use std::mem::{self, MaybeUninit}; let x: i32 = unsafe { mem::uninitialized() }; // undefined behavior! // equivalent code with `MaybeUninit` let x: i32 = unsafe { MaybeUninit::uninitialized().into_initialized() }; // undefined behavior!Run
(Notice that the rules around uninitialized integers are not finalized yet, but until they are, it is advisable to avoid them.)
MaybeUninit
serves to enable unsafe code to deal with uninitialized data:
it is a signal to the compiler indicating that the data here might not
be initialized:
#![feature(maybe_uninit)] use std::mem::MaybeUninit; // Create an explicitly uninitialized reference. The compiler knows that data inside // a `MaybeUninit` may be invalid, and hence this is not UB: let mut x = MaybeUninit::<&i32>::uninitialized(); // Set it to a valid value. x.set(&0); // Extract the initialized data -- this is only allowed *after* properly // initializing `x`! let x = unsafe { x.into_initialized() };Run
The compiler then knows to not optimize this code.
Methods
impl<T> MaybeUninit<T>
[src]
pub fn new(val: T) -> MaybeUninit<T>
[src]
Create a new MaybeUninit
initialized with the given value.
Note that dropping a MaybeUninit
will never call T
's drop code.
It is your responsibility to make sure T
gets dropped if it got initialized.
pub fn uninitialized() -> MaybeUninit<T>
[src]
Creates a new MaybeUninit
in an uninitialized state.
Note that dropping a MaybeUninit
will never call T
's drop code.
It is your responsibility to make sure T
gets dropped if it got initialized.
pub fn zeroed() -> MaybeUninit<T>
[src]
Creates a new MaybeUninit
in an uninitialized state, with the memory being
filled with 0
bytes. It depends on T
whether that already makes for
proper initialization. For example, MaybeUninit<usize>::zeroed()
is initialized,
but MaybeUninit<&'static i32>::zeroed()
is not because references must not
be null.
Note that dropping a MaybeUninit
will never call T
's drop code.
It is your responsibility to make sure T
gets dropped if it got initialized.
ⓘImportant traits for &'_ mut Ipub fn set(&mut self, val: T) -> &mut T
[src]
Sets the value of the MaybeUninit
. This overwrites any previous value without dropping it.
For your convenience, this also returns a mutable reference to the (now safely initialized)
contents of self
.
pub fn as_ptr(&self) -> *const T
[src]
Gets a pointer to the contained value. Reading from this pointer or turning it
into a reference will be undefined behavior unless the MaybeUninit
is initialized.
pub fn as_mut_ptr(&mut self) -> *mut T
[src]
Gets a mutable pointer to the contained value. Reading from this pointer or turning it
into a reference will be undefined behavior unless the MaybeUninit
is initialized.
pub unsafe fn into_initialized(self) -> T
[src]
Extracts the value from the MaybeUninit
container. This is a great way
to ensure that the data will get dropped, because the resulting T
is
subject to the usual drop handling.
Safety
It is up to the caller to guarantee that the MaybeUninit
really is in an initialized
state. Calling this when the content is not yet fully initialized causes undefined
behavior.
ⓘImportant traits for &'_ mut Ipub unsafe fn get_ref(&self) -> &T
[src]
Gets a reference to the contained value.
Safety
It is up to the caller to guarantee that the MaybeUninit
really is in an initialized
state. Calling this when the content is not yet fully initialized causes undefined
behavior.
ⓘImportant traits for &'_ mut Ipub unsafe fn get_mut(&mut self) -> &mut T
[src]
Gets a mutable reference to the contained value.
Safety
It is up to the caller to guarantee that the MaybeUninit
really is in an initialized
state. Calling this when the content is not yet fully initialized causes undefined
behavior.
pub fn first_ptr(this: &[MaybeUninit<T>]) -> *const T
[src]
Gets a pointer to the first element of the array.
pub fn first_ptr_mut(this: &mut [MaybeUninit<T>]) -> *mut T
[src]
Gets a mutable pointer to the first element of the array.
Auto Trait Implementations
impl<T> Send for MaybeUninit<T> where
T: Send,
T: Send,
impl<T> Sync for MaybeUninit<T> where
T: Sync,
T: Sync,
Blanket Implementations
impl<T> From for T
[src]
impl<T, U> TryFrom for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<T, U> Into for T where
U: From<T>,
[src]
U: From<T>,
impl<T> Borrow for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,