is compare_exchange_weak for std::shared_ptr broken in msvs

is compare_exchange_weak for std::shared_ptr broken in msvs 2013?

本文关键字:shared ptr in msvs broken std compare exchange weak for is      更新时间:2023-10-16

请看样本

std::atomic < std::shared_ptr < int > > a;
std::shared_ptr < int > b;
std::shared_ptr < int > c = std::make_shared < int > (10);
while(a.compare_exchange_weak(b, c));
assert(a.load() == c);  
assert(a.load().use_count() == 2); // <- assertion is failed.

你觉得怎么样?是编译器错误吗?

在 win32 模式下使用 msvs 2013 生成

您的程序表现出未定义的行为。

29.5/1 有一个泛型类模板atomic<T>。模板参数的类型T应该是简单的可复制的(3.9)。

shared_ptr<int>不是普通的可复制的。

根据伊戈尔的回答,std::atomic<std::shared_ptr<T>>没有定义的行为。您需要使用非成员shared_ptr原子函数重载,如原子访问 [util.smartptr.shared.atomic] shared_ptr中所述C++ §20.7.2.5 中所述。

std::shared_ptr < int > a;
std::shared_ptr < int > b;
std::shared_ptr < int > c = std::make_shared < int > (10);
while(std::atomic_compare_exchange_weak(&a, &b, c))
  ;
assert(std::atomic_load(&a) == c);  
assert(std::atomic_load(&a).use_count() == 2);

在我看来,奇怪的是,该标准没有要求通过这些功能实现template <typename T> struct std::atomic<shared_ptr<T>>的部分专业化。

我在Microsoft的<memory>标头文档中没有看到非成员原子重载,因此它们可能不会在VS2013中实现。

问题是关于 C++11 但值得指出的是,自 C++20 以来,OP 代码是有效的,因为shared_ptrunique_ptr都有专门的std::atomic

请参阅:在 cpp 首选项std::atomic<std::shared_ptr<T>>

此外,使用 std::atomic_compare_exchange 的替代方法已在 C++20 中弃用。