Диагностическое правило основано на руководстве MISRA (Motor Industry Software Reliability Association) по разработке программного обеспечения.
Правило актуально только для C++.
Вызов некоторых функций не имеет смысла, если результат их работы не используется. Результат выполнения функций std::remove, std::remove_if, std::unique, std::empty или функции-члена empty контейнера должен быть обязательно использован в коде. Например, его можно передать в другую функцию, сохранить в переменную для дальнейшей логики или проверить в условии.
Если возвращаемое значение этих функций никак не обрабатывается, код обычно не выполняет ожидаемое действие. В таком случае состояние объектов или структура данных остаются неизменными, что приводит к некорректному поведению программы на следующих этапах её выполнения.
Рассмотрим первый пример:
void remove_odd(std::vector<int> &v)
{
std::remove_if(v.begin(), v.end(),
[](auto item)
{
return (item & 1) != 0;
});
}
Вызов функции std::remove_if, несмотря на её имя, не выполняет удаление элементов из вектора. Он всего лишь перемещает их внутри вектора так, что возвращённый итератор указывает на первый элемент, удовлетворяющий предикату. Диапазон элементов от этого итератора и до конца вектора предназначен в дальнейшем для удаления.
Чтобы завершить операцию и удалить требуемые элементы из вектора, необходимо передать возвращённый итератор в функцию-член std::vector<int>::erase:
void remove_odd(std::vector<int> &v)
{
auto it = std::remove_if(v.begin(), v.end(),
[](auto item)
{
return (item & 1) != 0;
});
v.erase(it, v.end());
}
Рассмотрим второй пример:
template <typename T>
void copy_elements(const std::vector<T> &src,
std::vector<T> &dst)
{
dst.empty();
dst.reserve(src.size());
for (const T &elem : src)
{
dst.push_back(elem);
}
}
Программист хотел очистить результирующий вектор перед его наполнением. Однако вызов std::vector<T>::empty не очищает контейнер, а всего лишь говорит о том, пустой он или нет.
Чтобы очистить вектор, нужно воспользоваться функцией-членом std::vector<T>::clear:
template <typename T>
void copy_elements(const std::vector<T> &src,
std::vector<T> &dst)
{
dst.clear();
dst.reserve(src.size());
for (const T &elem : src)
{
dst.push_back(elem);
}
}