Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Atomic variable with padding (compiler bug?) [duplicate]

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?

like image 915
Lingxi Avatar asked Mar 07 '23 19:03

Lingxi


1 Answers

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.

like image 121
Sam Varshavchik Avatar answered Mar 21 '23 00:03

Sam Varshavchik