Reputation: 5165
If sequenceNumber
is atomic<int>
(seq_no is just an int),
Why does
sequenceNumber.compare_exchange_strong(sequenceNumber, seq_no );
not compile ?
I had a comparison operation with the atomic variable sequenceNumber before the compare_exchange_strong
operation and wanted to check if the value of sequenceNumber had been changed by the other thread by the time I actually came to update it in my thread.
Something like this:
if ( seq_no > sequenceNumber )
sequenceNumber.compare_exchange_strong(sequenceNumber, seq_no);
I fixed it by:
int current_sequence_number = sequenceNumber.load();
if ( seq_no > current_sequence_number )
sequenceNumber.compare_exchange_strong(current_sequence_number, seq_no );
But I am wondering why the compiler does not allow me to use an atomic<int>
in place of the first argument, i.e. the "expected" parameter in the function call -
bool compare_exchange_strong( T& expected, T desired,
std::memory_order order =
std::memory_order_seq_cst );
What was the motivation behind disallowing an atomic variable in place of the expected argument especially when seq_no > sequenceNumber
seems to be allowed ?
By the way, is using seq_no > sequenceNumber
also wrong ? (even though it compiles) Should I go for seq_no > sequenceNumber.load()
in that case as well ?
Upvotes: 0
Views: 247
Reputation: 52471
atomic<T>::compare_exchange_strong
takes T&
as its first parameter. atomic<T>
is not convertible to T&
(even though it is convertible to an rvalue of type T
; such a conversion just calls load()
).
If atomic<T>
were convertible to T&
, it would effectively give unrestricted access to underlying raw storage, and allow users to modify it at will, bypassing any synchronization mechanisms. Which would thoroughly defeat the point of having an atomic
in the first place.
Upvotes: 1