to the top
close form
Для получения триального ключа
заполните форму ниже
Team license
Enterprise license
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

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

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, для которых, как вы считаете, можно запрограммировать исключение в диагностике, предлагаем отправить нам соответствующую информацию и синтетический пример кода. Мы постараемся доработать анализатор.

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

Популярные статьи по теме
Обзор плагина PVS-Studio для Visual Studio Code

Дата: 02 Фев 2023

Автор: Андрей Москалёв

Благодаря новому плагину PVS-Studio преимущества статического анализа теперь доступны и при работе с редактором Visual Studio Code. В этой статье мы разберём использование плагина от этапа установки …
Изменения в PVS-Studio, о которых полезно знать

Дата: 31 Янв 2023

Автор: Сергей Васильев

В этой статье расскажу о том, что появилось в PVS-Studio за последние три года, и чем это полезно пользователям анализатора. Статья модульная: можно не читать от начала до конца, а посмотреть только …
C++ — язык 2022 года. Почему так, и что с другими языками?

Дата: 20 Янв 2023

Автор: Сергей Васильев

C++ становится языком 2022 года по версии TIOBE, обгоняя Python. Rust, C#, Go и прочие — далеко позади. Странно? Сейчас разберёмся.
PVS-Studio в 2022 году

Дата: 19 Янв 2023

Автор: Полина Алексеева

На дворе январь 2023, а значит, самое время подвести итоги уже прошлого 2022 года. Мы расскажем, чем занимались, и покажем, что нового появилось в анализаторе за это время. Давайте вместе взглянем на…
PVS-Studio: 2 фишки для быстрого старта

Дата: 08 Дек 2022

Автор: Сергей Васильев

В этой заметке расскажу, как легко начать использовать PVS-Studio. Рассмотрим два сценария: когда вы пробуете анализатор впервые и когда внедряете его в проект.

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

Следующие комментарии next comments
close comment form
Unicorn with delicious cookie
Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо