﻿# Как быстро посмотреть интересные предупреждения, которые выдает анализатор PVS\-Studio для C и C\+\+ кода?

Время от времени программисты, которые начинают знакомиться с анализатором кода PVS\-Studio, спрашивают: "Есть ли список предупреждений, которые точно указывают на ошибки?" Такого списка нет по той причине, что неинтересные \(ложные\) предупреждения в одном проекте, в другом оказываются очень важными и полезными\. Однако начать знакомство с анализатором с самых интересных предупреждений вполне можно\. Давайте рассмотрим эту тему подробнее\.

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

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

## Шаг 1

![0633_PVS_Studio_best_rules_ru/image2.png](https://import.viva64.com/docx/blog/0633_PVS_Studio_best_rules_ru/image2.png)

Отключите все типы предупреждений кроме основных \(GA\)\. Распространённая ошибка: включить все виды предупреждений\. Неопытным пользователям кажется, что чем больше всего включить, тем лучше\. Это не так\! Есть наборы диагностик, такие как 64\-битные проверки и MISRA\-правила, которые следует использовать, только чётко представляя, что это такое и как с ними работать\. Например, включив MISRA\-диагностики для обыкновенной прикладной программы, вы утонете в десятках, тысячах или сотнях тысяч сообщений типа:

* [V2506](https://pvs-studio.ru/ru/docs/warnings/v2506/)\. MISRA\. A function should have a single point of exit at the end\.
* [V2507](https://pvs-studio.ru/ru/docs/warnings/v2507/)\. MISRA\. The body of a loop\\conditional statement should be enclosed in braces\.
* [V2523](https://pvs-studio.ru/ru/docs/warnings/v2523/)\. MISRA\. All integer constants of unsigned type should have 'u' or 'U' suffix\.

Большинство MISRA\-предупреждений указывают не на ошибки, а запахи кода\. Естественно, человек начинает задаваться вопросами\. Как в массе всех этих предупреждений найти что\-то интересное? Диагностики под какими номерами он должен смотреть? Это неправильные вопросы\. Нужно просто отключить набор MISRA\. Это стандарт для написания качественного кода для встраиваемых устройств\. Суть стандарта: сделать код крайне простым и понятным\. Не надо пытаться применить его там, где он неуместен\.

Примечание\. Да, в стандарте MISRA есть правила, нацеленные на выявление настоящих ошибок\. Пример: [V2538](https://pvs-studio.ru/ru/docs/warnings/v2538/) \- The value of uninitialized variable should not be used\. Но не бойтесь отключить MISRA\-стандарт\. Вы ничего не потеряете\. Настоящие ошибки будут всё равно найдены в рамках диагностик общего назначения \(GA\)\. Например, неинициализированная переменная будет найдена благодаря диагностике [V614](https://pvs-studio.ru/ru/docs/warnings/v614/)\.

## Шаг 2

![0633_PVS_Studio_best_rules_ru/image3.png](https://import.viva64.com/docx/blog/0633_PVS_Studio_best_rules_ru/image3.png)

Любой статический анализатор при первых запусках выдаёт ложные срабатывания и требует определённой настройки\. С этим ничего нельзя сделать, но это не так страшно, как может показаться\. Даже простая быстрая настройка позволяет убрать большинство ложных предупреждений и начать знакомиться с уже вполне адекватным отчётом\. Подробнее говорить про это не будем, так как я уже много раз писал про это, например, в этой статье: "[Характеристики анализатора PVS\-Studio на примере EFL Core Libraries, 10\-15% ложных срабатываний](https://pvs-studio.ru/ru/blog/posts/cpp/0523/)"\.

Потратьте немного времени на отключение явно неактуальных предупреждений и борьбу с ложными срабатываниями из\-за макросов\. Макросы вообще являются основным источником ложных срабатываний, так как предупреждение появляется везде, где используется неудачно реализованный макрос\. Для подавления предупреждений в макросах, рядом с их объявлением можно разместить комментарии специального вида\. Подробнее формат написания комментариев рассматривается в [документации](https://pvs-studio.ru/ru/docs/manual/0017/)\.

Да, первоначальная настройка отнимет немного времени, но кардинально улучшит восприятие отчёта за счёт исключения отвлекающего шума\. Уделите этому немного времени\. Если есть какие\-то затруднения или вопросы, мы всегда готовы помочь и подсказать как лучше настроить анализатор\. Не стесняйтесь [написать](https://pvs-studio.ru/ru/about-feedback/) и задать нам вопросы\.

## Шаг 3

![0633_PVS_Studio_best_rules_ru/image4.png](https://import.viva64.com/docx/blog/0633_PVS_Studio_best_rules_ru/image4.png)

Начать изучать предупреждения с 1 уровня\. И только затем смотреть 2 и 3\. Уровни предупреждений являются ничем иным, как достоверностью предупреждения\. Предупреждения 1\-го уровня с большей вероятностью указывают на настоящую ошибку, чем 2\.

Можно сказать, что выбирая "смотреть 1 уровень", вы нажимаете кнопку "смотреть самые интересные ошибки"\.

Более подробно классификация предупреждений PVS\-Studio по уровням описана в статье "[Как и почему статические анализаторы борются с ложными срабатываниями](https://pvs-studio.ru/ru/blog/posts/cpp/0488/)"\.

## Так почему всё\-таки нет списка?

![0633_PVS_Studio_best_rules_ru/image5.png](https://import.viva64.com/docx/blog/0633_PVS_Studio_best_rules_ru/image5.png)

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

Рассмотрим предупреждение [V550](https://pvs-studio.ru/ru/docs/warnings/v550/)\. Предупреждение выявляет потенциальную ошибку, связанную с тем, что для сравнения чисел с плавающей точкой используется оператор \=\= или \!\=\.

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

Действительно, в большинстве приложений типы float/double используются в очень простых алгоритмах\. И часто сравнение с константой используется исключительно для того, чтобы проверить, задано ли некое значение по умолчанию, или оно изменилось\. В этом случае точная проверка вполне уместна\. Поясню это псевдокодом\.

```cpp
float value = 1.0f;
if (IsUserInputNewValue())
  value = GetUserValue();
if (value == 1.0f)
  DefaultBehavior();
else
  Foo(value);
```

Здесь сравнение _\(value \=\= 1\.0f\)_ корректно и безопасно\.

Значит ли это, что V550 является неинтересной диагностикой? Нет\. Всё зависит от проекта\. Процитирую фрагмент из статьи "[О том, как мы опробовали статический анализ на своем проекте учебного симулятора рентгенэндоваскулярной хирургии](https://pvs-studio.ru/ru/blog/posts/cpp/0331/)", написанной одним из наших пользователей\.

Итак, на что здесь обращает наше внимание статический анализатор:

V550 An odd precise comparison: t \!\= 0\. It's probably better to use a comparison with defined precision: fabs\(A \- B\) \> Epsilon\. objectextractpart\.cpp 3401

```cpp
D3DXVECTOR3 N = VectorMultiplication(
                  VectorMultiplication(V-VP, VN), VN);
float t = Qsqrt(Scalar(N, N));
if (t!=0)
{
  N/=t;
  V = V - N * DistPointToSurface(V, VP, N);
}
```

Подобные ошибки повторяются достаточно часто в данной библиотеке\. Не скажу, что это стало для меня неожиданностью\. Уже ранее наталкивался на некорректную работу с числами с плавающей точкой в этом проекте\. Однако систематически проверять исходники на этот счет не было ресурсов\. По результатам проверки стало ясно, что нужно дать разработчику почитать что\-то для расширения кругозора в части работы с числами с плавающей точкой\. Скинул ему ссылки на пару хороших статей\. Посмотрим на результат\. Сложно однозначно сказать, вызывает ли эта ошибка реальные сбои в работе программы\. Текущее решение выставляет ряд требований к исходной полигональной сетке артерий, по которым моделируется растекание рентгеноконтрастного вещества\. Если требования не выполнены, то возможны падения программы, или явно некорректная работа\. Часть из этих требований получена аналитически, а часть \- эмпирически\. Не исключено, что эта вторая часть требований растет как раз из некорректной работы с числами с плавающей точкой\. Нужно отметить, что не все найденные случаи употребления точного сравнения чисел с плавающей точкой являлись ошибкой\.

Как видите, то что неинтересно в одних проектах, представляет интерес в других\. Это делает невозможным создание списка "самого интересного"\.

Примечание\. Имеется возможность задавать с помощью настроек уровень предупреждений\. Например, если вы считаете, что диагностика V550 заслуживает пристального внимания, вы можете переместить её с третьего уровня на первый\. Данный вид настроек описан в [документации](https://pvs-studio.ru/ru/docs/manual/0040/) \(см\. "Как задать свой уровень для конкретной диагностики"\)\.

## Заключение

![0633_PVS_Studio_best_rules_ru/image6.png](https://import.viva64.com/docx/blog/0633_PVS_Studio_best_rules_ru/image6.png)

Теперь вы знаете, как начать изучение предупреждений анализатора, рассматривая самые интересные из них\. И не забывайте заглядывать в документацию, чтобы познакомиться с детальным описанием предупреждений\. Иногда бывает, что за невзрачным, на первый взгляд, предупреждением кроется ад\. Пример таких диагностик: [V597](https://pvs-studio.ru/ru/docs/warnings/v597/), [V1026](https://pvs-studio.ru/ru/docs/warnings/v1026/)\. Спасибо за внимание\.