Reputation: 14967
I use std::atomic
for atomicity. Still, somewhere in the code, atomicity is not needed by program logic. In this case, I'm wondering whether it is OK, both pedantically and practically, to use constructor in place of store()
as an optimization. For example,
// p.store(nullptr, std::memory_order_relaxed);
new(p) std::atomic<node*>(nullptr);
Upvotes: 0
Views: 141
Reputation: 473437
In accord with the standard, whether this works depends entirely on the implementation of std::atomic<T>
. If it is lock-free for that T
, then the implementation probably just stores a T
. If it isn't lock-free, things get more complex, since it may store a mutex
or some other thing.
The thing is, you don't know what std::atomic<T>
stores. This matters because if it stores a const
-qualified object or a reference type, then reusing the storage here will cause problems. The pointer returned by placement-new
can certainly be used, but if a const
or reference type is used, the original object name p
cannot.
Why would std::atomic<T>
store a const
or reference type? Who knows; my point is that, because its implementation is not under your control, then pedantically you cannot know how any particular implementation behaves.
As for "practically", it's unlikely that this will cause a problem. Especially if the atomic<T>
is always lock-free.
That being said, "practically" should also include some notion of how other users will interpret this code. While people experienced with doing things like reusing storage will be able to understand what the code is doing, they will likely be puzzled by why you're doing it. That means you'll need to either stick a comment on that line or make a (template) function non_atomic_reset
.
Also, it should be noted that std::shared_ptr
uses atomic increments/decrements for its reference counter. I bring that up because there is no std::single_threaded_shared_ptr
that doesn't use atomics, or a special constructor that doesn't use atomics. So even in cases where you're using shared_ptr
in pure single-threaded code, those atomics are still firing. This was considered a reasonable tradeoff by the C++ standards committee.
Atomics aren't cheap, but they're not that expensive (most of the time) that using unusual mechanisms like this to bypass an atomic store is a good idea. As always, profile to see if the code obfuscation is worth it.
Upvotes: 3