我在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
计算,并导致意外结果。我想知道标准对此有何看法。这是编译器错误吗?
答案 0 :(得分:6)
compare_exchange_strong
()和compare_exchange_weak
()执行比较“as if by std::memcmp
”,并且只有在它们是“按位相等”时才会影响交换。当然,所涉及的对象中存在任何填充,但尚未明确初始化,这使得比较结果不是很有用。
另请注意,您的结构没有指定正式的==
运算符;但即使你定义了一个,它也不会被使用。