Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
close form

Заполните форму в два простых шага ниже:

Ваши контактные данные:

Шаг 1
Поздравляем! У вас есть промокод!

Тип желаемой лицензии:

Шаг 2
Team license
Enterprise license
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности
close form
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Бесплатная лицензия PVS‑Studio для специалистов Microsoft MVP
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Мне интересно попробовать плагин на:
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
check circle
Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте, отфильтровано ли письмо в одну из следующих стандартных папок:

  • Промоакции
  • Оповещения
  • Спам

Вебинар: Парсим С++ - 25.10

>
>
>
V825. Expression is equivalent to movin…
menu mobile close menu
Проверка проектов
Сообщения PVS-Studio
Диагностики общего назначения (General Analysis, C++)
Диагностики общего назначения (General Analysis, C#)
Диагностики общего назначения (General Analysis, Java)
Микрооптимизации (C++)
Диагностика 64-битных ошибок (Viva64, C++)
Реализовано по запросам пользователей (C++)
Cтандарт MISRA
Стандарт AUTOSAR
Стандарт OWASP (C#)
Проблемы при работе анализатора кода
Дополнительная информация
toggle menu Оглавление

V825. Expression is equivalent to moving one unique pointer to another. Consider using 'std::move' instead.

01 Июн 2020

Анализатор обнаружил фрагмент кода, в котором совместно используются функции 'std::unique_ptr::reset' и 'std::unique_ptr::release'.

Рассмотрим простой пример кода:

void foo()
{
  auto p = std::make_unique<int>(10);
  ....
  std::unique_ptr<int> q;
  q.reset(p.release());
  ....
}

Формально, такой вызов эквивалентен перемещению умного указателя:

void foo()
{
  auto p = std::make_unique<int>(10);
  ....
  auto q = std::move(p);
  ....
}

В данном случае, предложение анализатора заменить цепочку вызовов 'q.reset(p.release())' на 'q = std::move(p) ' улучшит прозрачность кода. Однако, может возникнуть ситуация, когда перемещение умного указателя будет являться обязательным. Например, при использовании пользовательского функционального объекта для освобождения ресурса:

class Foo { .... };

struct deleter
{
  bool use_free;

  template<typename T>
  void operator()(T *p) const noexcept
  {
    if (use_free)
    {
      p->~T();
      std::free(p);
    }
    else
    {
      delete p;
    }    
  }
};

Рассмотрим два небольших примера, первый с перемещением умного указателя с пользовательским функциональным объектом для освобождения ресурса, при помощи паттерна 'reset' - 'release':

void bar1()
{
  std::unique_ptr<Foo, deleter> p { (int*) malloc(sizeof(Foo)),
                                     deleter { true } };
  new (p.get()) Foo { .... };

  std::unique_ptr<Foo, deleter> q;

  q.reset(p.release()); // 1
}

и второй пример, с помощью функции 'std::move':

void bar2()
{
  std::unique_ptr<Foo, deleter> p { (int*) malloc(sizeof(Foo)),
                                    deleter { true } };
  new (p.get()) Foo { .... };

  std::unique_ptr<Foo, deleter> q;

  q = std::move(p);     // 2
}

В втором примере при перемещении указателя 'p' в 'q' функция 'std::move' позволит переместить также и функциональный объект типа 'deleter' для освобождения ресурса. В первом примере цепочка вызовов 'q.reset(p.release())' этого не сделает. Это приведет к тому, что исходный объект типа 'Foo', аллоцированный на куче через вызов 'malloc' и сконструированный оператором 'placement new', будет неверно освобожден путем вызова оператора 'delete'. Такой код неминуемо приведёт к неопределённому поведению программы.