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

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

ec2a183069835fd4a4203ec7196695a9.png


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

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


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

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

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

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

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

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

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;
}


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

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

04b0d5022b3a6cfadc4732dce7842da7.png


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

d51k2edrgxyrg5voswox_46pg3o.png


Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Andrey Karpov. Upsetting Opinions about Static Analyzers.

© Habrahabr.ru