Is it UB to have uninitialized value in UnsafeCell?

According to example in UnsafeCell in std::cell - Rust, it says " Gradual initialization of an UnsafeCell requires raw_get , as calling get would require creating a reference to uninitialized data:"

// example from rust-std docs
let m = MaybeUninit::<UnsafeCell<i32>>::uninit();
unsafe { UnsafeCell::raw_get(m.as_ptr()).write(5); }
let uc = unsafe { m.assume_init() };

assert_eq!(uc.into_inner(), 5);

If I implement same function as below, is it undefined behavior?
get_mut just return reference to &mut MaybeUninit, and call the write method, which should be safe according to MaybeUinit docs, but then why the above docs says " Gradual initialization of an UnsafeCell requires raw_get

let mut m = UnsafeCell::new(MaybeUninit::<i32>::uninit());
// Is it UB?
m.get_mut().write(5);

assert_eq!(unsafe {m.into_inner().assume_init()}, 5);

Basically, what it's trying to say is that you should not create an &mut i32 before having initialized it.

Normally, you put the UnsafeCell outside the MaybeUninit, which will let you sidestep this kind of issue completely.

1 Like

Does the docs trying to say to avoid usage &*m.as_ptr() like below? Which we reference to uninitailized value of UnsafeCell<i32> not the i32 itself.

unsafe { UnsafeCell::get(&*m.as_ptr()).write(5); }

Yes.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.