﻿# Обидно за мнения про статические анализаторы кода

Инструменты статического анализа кода ушли далеко вперёд\. Это вовсе не те "линтеры", которые активно применялись 20 лет тому назад\. Однако многие по\-прежнему относятся к ним как к очень простым инструментам\. Обидно\. Обидно как за методологию анализа кода в целом, так и за инструмент PVS\-Studio\.

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

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

```cpp
if (A[0] == 0)
{
  X = Y;
  if (A[0] == 0)
    ....
}
```

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

На это был получен комментарий приблизительно следующего содержания:

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

Мне грустно\. Программисты до сих пор думают, что анализаторы кода построены на регулярных выражениях\. Мол, нашли два одинаковых вложенных _if_ и ругаемся :\(\.

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

Именно так и поступает статический анализатор PVS\-Studio\. Взглянем на следующий синтетический пример:

```cpp
char get();
int foo(char *p, bool arg)
{
    if (p[1] == 1)
    {
        if (arg)
            p[0] = get();
        if (p[1] == 1)          // Warning
            return 1;
    }
    if (p[2] == 2)
    {
        if (arg)
            p[2] = get();
        if (p[2] == 2)          // Ok
            return 2;
    }
    return 3;
}
```

Код содержит два похожих блока\. В одном проверяемая переменная не меняется, а во втором меняется\. Поэтому анализатор [выдаёт](https://godbolt.org/z/636Yo5) предупреждение только для первого блока: V547 Expression 'p\[1\] \=\= 1' is always true\.

Программисты могут не переживать\. Современные инструменты продвинуты и выдают предупреждения только на действительно подозрительный код\. Бывают ложные срабатывания, но, как правило, они связаны с наличием запутанного кода, в котором даже человеку бывает непросто разобраться\.

[![getTrialImageLink](https://cdn.pvs-studio.ru/media/get_trial_insert_ru.png)](https://pvs-studio.ru/ru/pvs-studio-download/)

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

1. [Примеры ошибок, обнаруженных с помощью диагностики V547](https://pvs-studio.ru/ru/blog/examples/v547/)\.
1. [Статический анализ и регулярные выражения](https://pvs-studio.ru/ru/blog/posts/cpp/0087/) \(почему это плохая идея :\)\.
1. [Технологии, используемые в анализаторе кода PVS\-Studio для поиска ошибок и потенциальных уязвимостей](https://pvs-studio.ru/ru/blog/posts/cpp/0592/)\.
1. [Продолжение: обидно за мнения про статические анализаторы кода](https://pvs-studio.ru/ru/blog/posts/cpp/0767/)\.