C++’s shared pointer has the same problem; Rust avoids it by having two types (Rc and Arc) that the developer can select from (and which the compiler will prevent you from using unsafely).
C++’s shared pointer has the same problem; Rust avoids it by having two types (Rc and Arc) that the developer can select from (and which the compiler will prevent you from using unsafely).
It doesn't. C++'s shared pointers use atomics, just like Rust's Arc does. There's no good reason (unless you have some very exotic requirements, into which I won't get into here) to implement shared pointers with mutexes. The implementation in the blog post here is just suboptimal.
(But it's true that C++ doesn't have Rust's equivalent of Rc, which means that if you just need a reference counted pointer then using std::shared_ptr is not a zero cost abstraction.)
I'd be interested to know what you are thinking.
The primary exotic thing I can imagine is an architecture lacking the ability to do atomic operations. But even in that case, C11 has atomic operations [1] built in. So worst case, the C library for the target architecture would likely boil down to mutex operations.
// Not real MIPS, just what I've gleaned from a brief look at some docs
LOAD addr, register
ADD 1, register
STORE register, addr
The LOAD and STORE are atomic, but the `ADD` happens out of band.That's a problem if any sort of interrupt happens (if you are multi-threading then a possibility). If it happens at the load, then a separate thread can update "addr" which mean the later STORE will stomp on what's there.
x86 and ARM can do
ADD 1, addr
as well as other instructions like "compare and swap" LOAD addr, register
MOV register, register2
ADD 1, register2
COMPARE_AND_SWAP addr, register, register2
if (cas_failed) { try again } loop: LL r2, (r1)
ADD r3, r2, 1
SC r3, (r1)
BEQ r3, 0, loop
NOP