Was Rc formerly laid out differently?

Something I thought I knew about the standard library: Rc<T> is represented as a pointer to the T field of one of these:

struct RcBox<T: ?Sized> {
    strong: Cell<usize>,
    weak: Cell<usize>,
    value: T,
}

This means that Deref compiles to a no-op, while cloning and dropping have to subtract from the pointer to get to the reference count fields.

But this is totally false, as can be seen by looking at the source: Rc<T> contains a NonNull<RcBox<T>> that points to the box itself, not its T field. According to git blame it has been this way forever.

Does anybody know where I got this strange idea about the representation of Rc?

Maybe you originally learned this about a type from a third-party crate, like triomphe::OffsetArc, and later misremembered it as referring to libstd?

1 Like

That must be it!

Rc::into_raw/from_raw have this weird property.

4 Likes

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.