Each instantiation and full specialization of the std::atomic template defines an atomic type. Objects of atomic types are the only C++ objects that are free from data races; that is, if one thread writes to an atomic object while another thread reads from it, the behavior is well-defined.
std::string certainly does not meet the std::atomic<T> requirement that the template parameter T be trivially copyable, so the standard places no requirements on the implementation.
Yes, it would be threadsafe. Assuming of course there are no bugs in the std::atomic implementation - but it's not usually hard to get right. This is exactly what std::atomic is meant to do.
(C++11) [edit] The atomic library provides components for fine-grained atomic operations allowing for lockless concurrent programming. Each atomic operation is indivisible with regards to any other atomic operation that involves the same object. Atomic objects are free of data races.
According to this prefix std::atomic<T>::operator++
returns a T
, so this code only increments v
once:
template<class T> void addTwo(std::atomic<T>& v) {
++(++v);
}
Also, std::atomic<T>::operator=
apparently returns a T
, so this code dereferences an invalid pointer that used to point to a temporary T
:
template<class T>
void setOneThenTwo(std::atomic<T>& v) {
auto ptr = &(v = 1);
*ptr = 2;
}
I am most certainly not suggesting that these code patterns are good practice, however it is highly surprising to me that std::atomic
breaks them. I always expect operator=
and prefix operator++
to return a reference to *this
.
Question: Is cppreference right about the return types here, and if so, is there a good reason for having std::atomic
behave differently than built-in types in this regard?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With