﻿# Пример, как в PVS\-Studio появляются новые диагностики

Пользователи иногда спрашивают, как появляются новые диагностики в статическом анализаторе PVS\-Studio\. Мы отвечаем, что черпаем вдохновение из разнообразнейших источников: книг, стандартов кодирования, собственных ошибок, писем наших пользователей и так далее\. Сегодня мы придумали новую интересную диагностику и решили рассказать историю, как это произошло\.

![0814_new_rule_example_ru/image1.png](https://import.viva64.com/docx/blog/0814_new_rule_example_ru/image1.png)

Всё началось с проверки проекта COVID\-19 CovidSim Model и [статьи](https://pvs-studio.ru/ru/blog/posts/cpp/0796/) про неинициализированную переменную\. Проект оказался маленьким и написанным с использованием современного стандарта языка C\+\+\. Это значит, что он отлично может пополнить базу тестовых проектов для регрессионного тестирования ядра анализатора PVS\-Studio\.

Однако, прежде чем пополнить базу новым проектом, полезно просмотреть выдаваемые предупреждения, чтобы выявить новые закономерности \(паттерны\) ложных срабатываний и выписать их для дальнейшей доработки анализатора\. Также это дополнительная возможность заметить, что ещё что\-то не так\. Например, сообщение неудачно описывает ошибку для определённой конструкции кода\. 

Программист, которому поручили добавить проект в тестовую базу, подошёл к задаче основательно и решил заглянуть в раздел MISRA\-диагностик\. Вообще, это делать было необязательно, так как это весьма специфичная группа диагностик, которую нет смысла включать для таких проектов, как CovidSim\.

MISRA С и MISRA C\+\+ диагностики предназначены для разработчиков встраиваемых систем, и их суть сводится к ограничению использования небезопасных конструкций программирования\. Например, не рекомендуется применять оператор _goto_ \([V2502](https://pvs-studio.ru/ru/docs/warnings/v2502/)\), так как он провоцирует создание сложного кода, в котором легко допустить логическую ошибку\. Подробнее с философией стандарта кодирования MISRA можно познакомиться в статье "[Что такое MISRA и как её готовить](https://pvs-studio.ru/ru/blog/posts/cpp/0702/)"\.

Для прикладного программного обеспечения, которым как раз и является проект CovidSim, включать набор MISRA диагностик не имеет смысла\. Пользователь просто утонет в огромном количестве малополезных для него сообщений\. Например, экспериментируя с этим набором диагностик, мы получали более миллиона предупреждений для некоторых открытых проектов среднего размера\. Грубо говоря, с точки зрения MISRA, в каждой третьей строчке кода может быть что\-то не так :\)\. Естественно, никто всё это смотреть и тем более править не будет\. Проект или сразу разрабатывается с учётом MISRA рекомендаций, или для него этот стандарт кодирования неактуален\.

Но мы отвлеклись от темы\. Так вот, бегло просматривая MISRA предупреждения, коллега зацепился взглядом за предупреждение [V2507](https://pvs-studio.ru/ru/docs/warnings/v2507/), выданное для этого фрагмента кода\.

```cpp
if (radiusSquared > StateT[tn].maxRad2) StateT[tn].maxRad2 = radiusSquared;
{
  SusceptibleToLatent(a->pcell);
  if (a->listpos < Cells[a->pcell].S)
  {
    UpdateCell(Cells[a->pcell].susceptible, a->listpos, Cells[a->pcell].S);
    a->listpos = Cells[a->pcell].S;
    Cells[a->pcell].latent[0] = ai;
  }
}
StateT[tn].cumI_keyworker[a->keyworker]++;
```

Правило V2507 заставляет оборачивать тела условных операторов в фигурные скобки\.

В первый момент наш дотошный коллега подумал, что анализатор дал сбой\. Ведь здесь есть блок текста в фигурных скобках\! Перед нами ложное срабатывание?

Давайте присмотримся\. Код только кажется корректным, но таковым не является\! Фигурные скобки не относятся к оператору _if_\.

Отформатируем код для наглядности:

```cpp
if (radiusSquared > StateT[tn].maxRad2)
  StateT[tn].maxRad2 = radiusSquared;

{
  SusceptibleToLatent(a->pcell);
  ....
}
```

Согласитесь, это красивый баг\. Он наверняка войдёт в Top10 C\+\+ ошибок, найденных нами в 2021 году\.

И что из этого следует? Подход, диктуемый стандартом MISRA, работает\! Да, он заставляет писать везде фигурные скобки\. Да, это утомительно\. Но это оправданная плата за повышение надёжности встроенных приложений, используемых в медицинской технике, автомобилях и других системах высокой ответственности\.

Хорошо, у разработчиков, использующих стандарт MISRA, всё нормально\. Однако рекомендовать всем подряд использовать фигурные скобки – это плохая идея\. Используя такой подход, очень легко довести анализатор до состояния, когда им станет невозможно пользоваться\. Будет так много сообщений, что их просто никто не будет смотреть\. 

Вот мы и добрались для появления идеи для новой диагностики общего назначения\. Можно сформулировать следующее правило\.

Выдать предупреждение, если для оператора _if_ выполняются следующие условия:

* весь условный оператор _if_ записан в одну строчку и имеет только _then_\-ветку;
* следующий statement после _if_ – это compound statement, и он находится не на той же строке, что и _if_\.

Заранее можно прогнозировать, что получится хорошее правило с низким количеством ложных срабатываний\.

Именно так эта идея сейчас оформлена в нашей системе учёта задач\. Возможно, в процессе реализации что\-то будет сделано по\-другому, но это уже неважно\. Главное, появится хорошее диагностическое правило, которое начнёт выявлять новый паттерн ошибки\. Далее мы распространим его на C\# и Java ядра анализатора PVS\-Studio\.

Только что мы рассмотрели интересный пример, как было сформулировано новое диагностическое правило, которое затем будет реализовано в PVS\-Studio\. Скажем спасибо проекту CovidSim, стандарту кодирования MISRA и наблюдательности нашего коллеги\.

Спасибо за внимание и следуйте за мной в мир С\+\+ и багов :\)\. [Twitter](https://twitter.com/Code_Analysis)\. 

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

1. [Технологии, используемые в анализаторе кода PVS\-Studio для поиска ошибок и потенциальных уязвимостей](https://pvs-studio.ru/ru/blog/posts/cpp/0592/)\.
1. [Под капотом PVS\-Studio для Java: разработка диагностик](https://pvs-studio.ru/ru/blog/posts/java/0752/)\.
1. [Использование машинного обучения в статическом анализе исходного кода программ](https://pvs-studio.ru/ru/blog/posts/0706/)\.