带填充的原子变量(编译器错误?)

时间:2018-02-23 12:02:01

标签: c++ c++14 padding atomic

我在Apple LLVM 9.0.0版(clang-900.0.39.2)和-std=c++14上发现了这种奇怪的行为。以下代码演示了它:

#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;
}

输出为0,而我预计它为1。当我将stru更改为:

时,问题就消失了
struct stru {
  std::uint64_t a; // original: std::uint32_t a;
  std::uint64_t b;
};

我能看到的唯一区别是原始版本有填充,而修改版本没有。看起来填充具有垃圾值,它涉及compare_exchange_strong计算,并导致意外结果。我想知道标准对此有何看法。这是编译器错误吗?

1 个答案:

答案 0 :(得分:6)

compare_exchange_strong()和compare_exchange_weak()执行比较“as if by std::memcmp”,并且只有在它们是“按位相等”时才会影响交换。当然,所涉及的对象中存在任何填充,但尚未明确初始化,这使得比较结果不是很有用。

另请注意,您的结构没有指定正式的==运算符;但即使你定义了一个,它也不会被使用。