Subject: Re: [boost] [Atomic] Rationale for preventing copy construction/assignment?
From: Rob Stewart (robertstewart_at_[hidden])
Date: 2013-05-30 05:22:22
On May 30, 2013, at 12:59 AM, Collin Dauphinee <collin_at_[hidden]> wrote:
> On 5/29/2013 8:49 PM, Steven Watanabe wrote:
>> On 05/29/2013 01:22 PM, Collin Dauphinee wrote:
>>> I've recently noticed that boost::atomic<T> prevents assignment from
>>> boost::atomic<T>, as well as copy construction. I'm having trouble understanding why this decision was made, as it makes boost::atomic<T> (and
>>> classes with a boost::atomic<T> member) very hard to store in containers, and I can't immediately see any safety issues that would be caused by allowing copy operations.
>>> What is the rationale for not allowing assignment or copy construction from another boost::atomic<T>?
>> How would you make it sequentially consistent
>> without using a mutex?
> I don't view an assignment as a single operation, so I wouldn't expect both reading the source and storing it's value in the destination to be sequentially consistent. I would expect an assignment to be a 'convenience' function wrapping store and load, because as far as I'm aware, there is no way to do this sequentially without a mutex.
Assignment is a load and a store, as you note, so it isn't atomic, which is the point of an atomic type, after all. Between the load and store, the source atomic's value can change, so the copy can be wrong, hence Steven's question.
> My issue is stemming from wanting to store an object containing a few member variables, one being an atomic counter, in an std::map. The work around is to either implement the assignment operator just to accomodate the counter, or wrapping the counter in a class providing the same interface. Both result in bad code, and I think this is something an average user would run into fairly often.
By denying copying, atomics prevent such misguided ideas. When adding atomics to a container, or removing them later, their contents would be suspect at best. This is never a good thing to permit by default.
> I imagine that the situation where a user actually cares about the sequential consistency of assignment would be very rare, and in the cases where the user does care, they would realize the cost of guaranteeing sequential consistency for an assignment and check the documentation. Again, this would be completely for convenience.
That's a very naive viewpoint. If one relies on complete understanding of documentation, which means the C++11 standard for std::atomics, few will be in the position you describe. Instead, the Right Thing (tm) is to deny unsafe usage at compile time. That forces one to abandon unsupported usage and may lead to reading more for better understanding.
For your use case, you can design the copy constructor of your class to read-then-write the atomics' values to effect copying if you are certain such copying is synchronized or only done in one thread.
(Sent from my portable computation engine)
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk