I found this weird behavior on Apple LLVM version 9.0.0 (clang-900.0.39.2) with -std=c++14
. The following code demonstrates it:
#include <cstdint>
#include <atomic>
#include <iostream>
struct stru {
std::uint32_t a;
std::uint64_t b;
};
int main() {
stru sa{}, sb{1, 1};
std::atomic<stru> atom(sa);
std::cout << atom.compare_exchange_strong(sa, sb) << std::endl;
}
The output is 0
while I expect it to be 1
. The issue is gone when I change stru
to:
struct stru {
std::uint64_t a; // original: std::uint32_t a;
std::uint64_t b;
};
The only difference I can see is that the original version has padding, while the modified version does not. Looks like the padding has garbage value in it, which is involved in the compare_exchange_strong
computation, and cause the unexpected result. I'm wondering what does the standard say about this. Is this a compiler bug?
compare_exchange_strong
() and compare_exchange_weak
() execute the comparison "as if by std::memcmp
", and effects the exchange only if they are "bitwise-equal". Of course, the presence of any padding in the objects involved, that's has not been explicitly initialized, makes the results of the comparison not very useful.
Also note that your structure does not have a formal ==
operator specified; but even if you defined one, it would not be used.
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