Сбой сравнения_обмена для std::shared_ptr в msvs 2013?
Посмотрите на образец, пожалуйста
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.
Как вы думаете? Это ошибка компилятора?
Сборка с msvs 2013 в режиме win32
2 ответа
Ваша программа демонстрирует неопределенное поведение.
29.5 / 1 Существует универсальный шаблон класса
atomic<T>
, Тип аргумента шаблонаT
должно быть легко копируемым (3.9).
shared_ptr<int>
не тривиально копируемый.
За ответ Игоря, std::atomic<std::shared_ptr<T>>
не имеет определенного поведения. Вы должны использовать не-член shared_ptr
перегрузка атомарных функций, как описано в C++11 §20.7.2.5 shared_ptr
атомарный доступ [util.smartptr.shared.atomic].
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 действителен, поскольку существует специализация дляstd::atomic
для обоих shared_ptr
а также unique_ptr
.
Видеть: std::atomic<std::shared_ptr<T>>
на cppreference
Кроме того, альтернатива использования std::atomic_compare_exchange
был устаревшим в C++20.