﻿# Анализатор PVS\-Studio на сайте godbolt\.org \(Compiler Explorer\) и предостережение

Мы добавили возможность экспериментировать со статическим анализатором кода PVS\-Studio на сайте godbolt\.org \(Compiler Explorer\)\. Поддерживается анализ C и C\+\+ кода\. Уверены, что это интересный и очень простой способ попробовать, как поведёт себя анализатор на тех или иных примерах кода\. Однако у нас есть опасение, что теперь программисты начнут пытаться оценивать возможности анализатора на синтетических примерах, а не запуская на реальных проектах\. Давайте попробуем разобраться, чем плох подход оценки, базирующийся на синтетических примерах\.

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

[Compiler Explorer](https://godbolt.org/) это интерактивный инструмент, который позволяет печатать код в одном окне и видеть результаты его компиляции в другом\.

[PVS\-Studio](https://pvs-studio.ru/ru/pvs-studio/) – это инструмент для выявления ошибок и потенциальных уязвимостей в исходном коде программ, написанных на языках С, C\+\+, C\# и Java\.

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

1. Зайти на сайт [godbolt\.org](https://godbolt.org/),
1. Во вкладке с выводом компилятора нажать "Add tool\.\.\.",
1. В выпадающем списке выбрать "PVS\-Studio"\.

Теперь вы можете проверять ваш код, просто вписав его в окне на сайте\. На данный момент поддерживаются все версии компиляторов GCC и Clang для платформ x86 и x64\.

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

Наша команда уже давно столкнулась с этой проблематикой\. Ещё в 2017 году я написал статью "[Почему я не люблю синтетические тесты](https://pvs-studio.ru/ru/blog/posts/cpp/0471/)"\. Рекомендую почитать её, она небольшая\. Сейчас я приведу ещё примеры\.

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

```cpp
int main()
{
  int *p = new int;
  *p = 1;
  return 1;
}
```

[Да, PVS\-Studio умеет выявлять утечки памяти](https://pvs-studio.ru/ru/blog/posts/cpp/0543/)\. Вот только здесь он [промолчит](https://godbolt.org/z/ok947p)\.

Для экспериментатора причина может быть неочевидна, и он сделает неправильные выводы\. Дело в том, что именно в функции _main_ очень часто программисты не освобождают память\. Настолько часто, что мы сделали специально исключение на этот случай\. Ведь на самом деле, беды нет\. После завершения работы функции _main_ память всё равно будет возвращена системе\.

Да, формально это всё равно ошибка\. Но на практике такой код так широко распространён, что нет смысла отвлекать людей подобными срабатываниями\. И помнится, кто\-то из пользователей тоже просил нас убрать предупреждения про утечки для _main_\.

Стоит поменять название функции и предупреждение вернётся\.

```cpp
int foo()
{
  int *p = new int;
  *p = 1;
  return 1;
}
```

Теперь анализатор [выдаст](https://godbolt.org/z/W3rSGM) ожидаемое предупреждение: <source\>:5:1: error: V773 The function was exited without releasing the 'p' pointer\. A memory leak is possible\.

Другой пример с функцией main\. Давайте сделаем в ней вечный цикл:

```cpp
int main()
{
  unsigned i = 0;
  while (1)
  {
      i++;
  }
  return 1;
}
```

Анализатор [молчит](https://godbolt.org/z/gCKqD4)\. Неужели он не видит подозрительный вечный цикл? Видит\. И это тоже распространённый паттерн корректного кода\. Так очень часто пишут разработчики программ для микроконтроллеров\. Почти всегда в таких программах есть вечный цикл, в котором что\-то делается\. Выход из функции _main_ не имеет смысла и никогда не осуществляется\. Там, собственно, и выходить\-то некуда :\)\.

И вновь, стоит поменять название функции, и анализатор выдаст предупреждение\.

```cpp
int foo()
{
  unsigned i = 0;
  while (1)
  {
      i++;
  }
  return 1;
}
```

Анализатор [сообщает](https://godbolt.org/z/4LewPr): <source\>:4:1: note: V776 Potentially infinite loop\.

Работа любого статического анализатора – это хрупкий баланс между бесконечным количеством малополезных сообщений и опасностью не сообщить про настоящую ошибку\. Теперь становится понятно, почему анализаторы кода столь чувствительны к тому, как составлены примеры\. И надо быть очень аккуратным при написании синтетических примеров\. И вдвойне надо быть аккуратным, если с помощью таких маленьких тестов вы захотите сравнивать инструменты анализа\. Лучше так не делать\.

Если кто\-то хочет лучше понять нашу философию реализации диагностик и отсечения ложных срабатываний, предлагаю взглянуть на две следующие статьи:

1. [Философия статического анализатора PVS\-Studio](https://pvs-studio.ru/ru/blog/posts/0516/);
1. [Как и почему статические анализаторы борются с ложными срабатываниями](https://pvs-studio.ru/ru/blog/posts/cpp/0488/)\.

Самый лучший способ попробовать анализатор кода и оценить его возможности – это запустить его на своем настоящем проекте\. Это легко сделать\. Просто [скачайте](https://pvs-studio.ru/ru/pvs-studio/download/) анализатор PVS\-Studio запустите\. Кстати, а для открытых проектов есть ещё и [бесплатная лицензия](https://pvs-studio.ru/ru/blog/posts/0614/)\.

Теперь вы предупреждены\. Пробуйте, экспериментируйте\. Но будьте аккуратны в выводах\.

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

1. [Пример на C](https://godbolt.org/z/TcLbMV);
1. [Пример на C\+\+](https://godbolt.org/z/qvVFGv)\.

Спасибо за внимание\.