Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
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
Ваше сообщение отправлено.

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


Если вы так и не получили ответ, пожалуйста, проверьте папку
Spam/Junk и нажмите на письме кнопку "Не спам".
Так Вы не пропустите ответы от нашей команды.

>
>
>
Ложноположительные срабатывания статиче…

Ложноположительные срабатывания статического анализатора кода

07 Июл 2021

Одним из недостатков методологии статического анализа кода является наличие ложноположительных (false positives) предупреждений. Инструмент сигнализирует о возможных проблемах там, где их нет.

Разработчики инструментов статического анализа кода прикладывают много усилий, чтобы сократить количество ложных срабатываний. У кого-то это получается лучше, у кого-то хуже. Важно принимать, что проблема ложных срабатываний неразрешима на теоретическом уровне. Можно стремиться к идеалу, но никогда не получится создать анализатор, который совсем не ошибается.

Причиной является проблема останова: это теорема, которая доказывает, что невозможно разработать общий алгоритм, который бы по исходному коду программы определял, зациклится она или завершится за конечное время. Расширением данной теоремы является теорема Райса, утверждающая, что для любого нетривиального свойства вычислимых функций определение того, вычисляет ли произвольная программа функцию с таким свойством, является алгоритмически неразрешимой задачей.

Впрочем, даже если не вдаваться в теорию, легко продемонстрировать ситуацию, когда неочевидно, содержит код ошибку или нет. Для примера возьмём диагностику V501, реализованную в анализаторе PVS-Studio.

Идея диагностики очень простая. Подозрительно, когда совпадает левый и правый операнд у операторов ==, <, >, && и так далее. Пример:

if (A == A)

Почти всегда это опечатка. Это подтверждается большим количеством ошибок, найденных данной диагностикой в реальных открытых проектах. Казалось бы, такая простая и удачная диагностика не может давать ложные срабатывания. К сожалению, это не так. Реальный корректный код из одной математической библиотеки:

__host__ __device__ inline int isnan(float x){
  return x != x;
}

Сравнивая переменную типа float саму с собой можно узнать, является её значение не числом (NaN) или нет.

NaN не равен ни одному другому значению (даже самому себе). Благодаря этому один из распространённых, однако неочевидных способов проверки результата на NaN — это сравнение полученной величины с самой собой.

Многие анализаторы выдадут на этот код предупреждение, хотя функция работает правильно. Конечно, для таких целей лучше использовать функцию std::isnan. Однако рассмотренный код корректен, и его аналоги встречаются в большом количестве приложений. Поэтому выдача предупреждений для сравнения двух одинаковых переменных в этом конкретном коде является ложным срабатыванием.

Анализатор PVS-Studio идёт дальше и пытается угадать, находится ли перед ним функция, выявляющая нечисла. Диагностика V501 промолчит, если сравниваются одинаковые переменные типа float и где-то рядом есть сочетание букв "NaN", "nan", "Not a Number" и т.д. То есть анализатор промолчит на показанный выше код.

К сожалению, хотя такие эмпирические исключения крайне полезны, они ненадёжны. Встретив где-то в тексте программы сравнение float переменной A == A и не имея дополнительных подсказок, анализатор будет вынужден выдать предупреждение. Однако, как мы теперь знаем, такой код может быть корректен, если программист хочет выявить наличие NaN. Да, такой код плох, так как путает не только анализатор, но и других программистов. Однако он может быть корректен и делать ровно то, что должен.

Таких неоднозначностей всегда много, и анализаторы кода балансируют между опасностью не сообщить о какой-то ошибке и опасностью выдать большое количество ложных срабатываний.

Большое количество ложных срабатываний плохо тем, что программист начинает пренебрежительно относиться к отчёту анализатора. И, встретив не очень понятное предупреждение, программист предрасположен сразу посчитать его ложным. Он не попытается разобраться подробнее. Это печально, так как часто анализаторы кода находят как раз неприметные ошибки в коде, который, на первый взгляд, выглядит хорошо. Примеры: 1, 2.

Чтобы компенсировать проблему ложных срабатываний, инструменты предлагают разнообразные вспомогательные механизмы, позволяющие настроить диагностики, подавить ложные предупреждения и отложить малозначимый технический долг на потом. См. также статью "Как внедрить статический анализатор кода в legacy проект и не демотивировать команду".

Если вы столкнулись с ложными срабатываниями PVS-Studio, для которых, как вы считаете, можно запрограммировать исключение в диагностике, предлагаем отправить нам соответствующую информацию и синтетический пример кода. Мы постараемся доработать анализатор.

Дополнительные ссылки:

Популярные статьи по теме


Комментарии (0)

Следующие комментарии next comments
close comment form