Will Rc<RefCell<T>> create two level indirections in the complied code?

I’m a cpper learning Rust now. This Rc<RefCell> to handle sharing+mutability looks like a shared_ptr<unique_ptr> to me. Hence I have a question about the complied code. Will there be two level pointers here which slightly degrades performance?

1 Like

RefCell stores its data inline, so no there is only 1 level of indirection from the Rc.


Got it. Thanks!

So that means RefCell is a stack variable wrapper simply for mutability convenience (checked at runtime).

Looking at the chapter about RefCell, I have an impression that it’s almost like a Box except that borrow rules are checked at run time. I think it might be worthwhile to mention some stack/heap difference of RefCell v.s. Box so it’s clear to the reader. Any other folks have the same feeling?

1 Like

That is correct

Yeah, looking at it, it does look misleading. Could you file an issue for it here

Hmmm, it’s a little bit more than a convenience in that shared mutability without an UnsafeCell, which RefCell builds upon, is UB in Rust. You can think of it like the UB of aliasing restrict pointers in c/++, except restrict is the opt-out default in Rust.


Done. Filed an issue here.

1 Like

I just had a look at the source code. RefCell contains an UnsafeCell<T>, with an UnsafeCell<T> just being a wrapper around T. It doesn’t look like RefCell<T> adds any unnecessary indirection.

pub struct RefCell<T: ?Sized> {
    borrow: Cell<BorrowFlag>,
    value: UnsafeCell<T>,

pub struct UnsafeCell<T: ?Sized> {
    value: T,