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
operator++returned a reference, it would have been a reference tostd::atomic<T>not toTin which case you would need to do an additionalloadto get the current value.Imagine you’ve got a DBMS and you need to maintain an ‘autoincrement’ field
With
operator++retuningTyou can do thisNow imagine
operator++returnsstd::atomic<T>&In that case when you do
return ++currentit will do two thingsThey are two totally independent operations. If other thread calls
nextin between you will get wrong value for your autoincrement field!