bobeff
bobeff

Reputation: 3739

Are Rust smart pointers std::rc::Rc and std::sync::Arc analogous to the C++ smart pointers std::shared_ptr and std::atomic_shared_ptr respectively?

Is there analogy between Rust smart pointers std::rc::Rc and std::sync::Arc with the C++ smart pointers std::shared_ptr and std::atomic_shared_ptr? For me, they look the same, but probably there are some implementation nuances. For example in C++ std::shared_ptr the reference count in the control block is atomic despite the pointer itself is not. Is it the same in Rust's std::rc::Rc?

Upvotes: 4

Views: 1870

Answers (2)

kmdreko
kmdreko

Reputation: 60002

Rust's Arc<T> is largely equivalent to C++'s shared_ptr<T>

Both are "smart pointers" that provide shared ownership of a value via reference counting. They both use atomics for internal operations so that ownership can be tracked between threads safely.

One notable difference is the C++ std::shared_ptr implementation provides an aliasing constructor where you can create a std::shared_ptr<U> for a nested field of a std::shared_ptr<T> such that the std::shared_ptr<U> tracks the root T object properly.

C++ has no equivalent of Rust's Rc<T>

The only difference between std::rc::Rc and std::sync::Arc is that the internal reference tracking is not atomic. This means it cannot be used between threads, but has the benefit of avoiding the potential costs of atomic operations.

Rust has no equivalent of C++'s atomic<shared_ptr<T>>

C++'s std::atomic is generic so its atomic pointer type is a std::atomic<T*> whereas Rust's just has the dedicated type std::sync::atomic::AtomicPtr<T>. C++ has a specialization for std::atomic<std::shared_ptr<T>> so that multiple threads can atomically access and modify the shared_ptr itself, not just the shared value. The std::atomic_shared_ptr mentioned by OP was not standardized in favor of this specialization.

There may exist libraries for the equivalents but I've only included what's in the respective standard libraries.

See also:

Upvotes: 13

Masklinn
Masklinn

Reputation: 42272

For example in C++ std::shared_ptr the reference count in the control block is atomic despite the pointer itself is not. Is it the same in Rust's std::rc::Rc?

No. Arc is the analogue to shared_ptr: the reference-counting is atomic (and thus thread-safe), the data is not (which is why you'll usually see Arc<Mutex<T>> or Arc<RwLock<T>> in order to allow mutation of the inner type, otherwise Arc will only provide read-only access).

Rc is completely unsynchronised, and in fact statically can not be moved between threads (it's !Send). There is no such type in the C++ standard library[0].

[0] although libstdc++ will use non-thread-safe shared_ptr if it believes multithreading is not involved, that's more of an optimisation / hack: https://snf.github.io/2019/02/13/shared-ptr-optimization/

Upvotes: 2

Related Questions