Cornstalks Cornstalks - 1 year ago 64
C++ Question

Is there a non-atomic equivalent of std::shared_ptr? And why isn't there one in <memory>?

This is a bit of a two part question, all about the atomicity of


As far as I can tell,
is the only smart pointer in
that's atomic. I'm wondering if there is a non-atomic version of
available (I can't see anything in
, so I'm also open to suggestions outside of the standard, like those in Boost). I know
is also atomic (if
isn't defined), but maybe there's another alternative? I'm looking for something that has the same semantics as
, but without the atomicity.

2. I understand why
is atomic; it's kinda nice. However, it's not nice for every situation, and C++ has historically had the mantra of "only pay for what you use." If I'm not using multiple threads, or if I am using multiple threads but am not sharing pointer ownership across threads, an atomic smart pointer is overkill. My second question is why wasn't a non-atomic version of
provided in C++11
? (assuming there is a why) (if the answer is simply "a non-atomic version was simply never considered" or "no one ever asked for a non-atomic version" that's fine!).

With question #2, I'm wondering if someone ever proposed a non-atomic version of
(either to Boost or the standards committee) (not to replace the atomic version of
, but to coexist with it) and it was shot down for a specific reason.

Answer Source

1. I'm wondering if there is a non-atomic version of std::shared_ptr available

Not provided by the standard. There may well be one provided by a "3rd party" library. Indeed, prior to C++11, and prior to Boost, it seemed like everyone wrote their own reference counted smart pointer (including myself).

2. My second question is why wasn't a non-atomic version of std::shared_ptr provided in C++11?

This question was discussed at the Rapperswil meeting in 2010. The subject was introduced by a National Body Comment #20 by Switzerland. There were strong arguments on both sides of the debate, including those you provide in your question. However, at the end of the discussion, the vote was overwhelmingly (but not unanimous) against adding an unsynchronized (non-atomic) version of shared_ptr.

Arguments against included:

  • Code written with the unsynchronized shared_ptr may end up being used in threaded code down the road, ending up causing difficult to debug problems with no warning.

  • Having one "universal" shared_ptr that is the "one way" to traffic in reference counting has benefits: From the original proposal:

    Has the same object type regardless of features used, greatly facilitating interoperability between libraries, including third-party libraries.

  • The cost of the atomics, while not zero, is not overwhelming. The cost is mitigated by the use of move construction and move assignment which do not need to use atomic operations. Such operations are commonly used in vector<shared_ptr<T>> erase and insert.

  • Nothing prohibits people from writing their own non-atomic reference-counted smart pointer if that's really what they want to do.

The final word from the LWG in Rapperswil that day was:

Reject CH 20. No consensus to make a change at this time.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download