I'd like to clone Rc<T>
from *const T
created by Rc::into_raw()
, without touching ownership of the original Rc behind the raw pointer.
I.e. what I wanted is:
fn clone_raw1(raw: *const T) -> Rc<T> {
// Restore `Rc` temporarily to clone.
let original = unsafe { Rc::from_raw(raw) };
// Clone `Rc`.
let cloned = Rc::clone(original);
// Make it pointer again so that the caller can continue using `raw`.
let raw2 = Rc::from_raw(original);
// I wish they were always identical...
assert_eq!(raw, raw2);
cloned
}
I checked the std reference but I don't find any guarantees of raw == raw2
.
(I think they would be always the same in the current std implementation, but I need the guarantee.)
So I searched issues and found Feature: Rc::clone_raw
(and for Arc) (#48108) and Add strong_count mutation methods to Rc (#83476), and then next question arises: am I allowed to call Rc::from_raw()
multiple times for a pointer created by single Rc::into_raw()
call?
fn clone_raw2(raw: *const T) -> Rc<T> {
// Obviously OK, as long as `Rc` behind `raw` is not yet dropped.
unsafe { Rc::increment_strong_count(raw) };
// Possibly more than one `Rc::from_ptr` for single `Rc::into_raw`...
// Is it allowed?
unsafe { Rc::from_raw(ptr) }
}
fn main() {
let raw = Rc::into_raw(Rc::new("hello".to_owned()));
let rc1 = clone_raw2(raw);
let rc2 = clone_raw2(raw);
let rc3 = clone_raw2(raw);
let rc0 = Rc::from_raw(raw);
// Four `Rc::from_raw()` calls for single `raw` pointer!
}
I think it is probably allowed (in the current std implementation), but I cannot find documentation that allows and guarantees it explicitly.
All examples for Rc
(https://doc.rust-lang.org/1.70.0/std/rc/struct.Rc.html) are carefully(?) written in a way every Rc::from_raw()
call corresponds to different Rc::into_raw()
.
So my question is:
- Is it allowed to call
Rc::from_raw()
multiple times for a pointer created by singleRc::into_raw()
, assuming the strong count is appropriately incremented? - Is there any documentation that describes about that explicitly?
- Additional question: Is there any guaranttee that the multiple
Rc
s sharing the single object return the identical pointer byRc::into_raw()
?- See
assert_eq!
in theclone_raw1()
example.
- See