﻿# Статистический анализ кода

Когда кто\-то в комментариях или при разговоре упоминает "**статистический** анализ кода", то почти наверняка он ошибся/оговорился и имел в виду "[**статический анализ кода**](https://pvs-studio.ru/ru/blog/terms/0046/)"\. Однако **статистический** анализ действительно существует\. Он является одним из методов поиска ошибок, используемых статическими анализаторами кода\.

Анализатор собирает статистику о некоторых артефактах программного кода и на её основе выявляет аномалии\. Рассмотрим, как это может выглядеть на практике\.

C и C\+\+ программисты иногда забывают, что числовые литералы, начинающиеся с 0, являются восьмеричными\. Программист случайно, или чтобы выровнять код, может написать 0020 вместо 20\. При этом не учитывая, что 0020 — это восьмеричная константа, равная числу 16 в десятичной системе счисления\.

Чтобы предотвратить такие ошибки, некоторые стандарты кодирования вообще запрещают использовать восьмеричные константы\. Примером могут служить стандарты MISRA C:2012 \(правило MISRA\-C\-7\.1\) и MISRA C\+\+:2008 \(правило MISRA\-CPP\-2\.13\.2\)\. Поэтому, если вы используете стандарт MISRA, анализатор PVS\-Studio позволяет найти восьмеричные константы с помощью диагностики [V2501](https://pvs-studio.ru/ru/docs/warnings/v2501/)\.

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

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

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

На этих принципах в анализаторе PVS\-Studio устроена диагностика [V536](https://pvs-studio.ru/ru/docs/warnings/v536/)\. Пример ошибки, найденной с помощью этой диагностики в проекте Chromium \(C\+\+\):

```cpp
// Coefficients used to convert from RGB to monochrome.
const uint32 kRedCoefficient = 2125;
const uint32 kGreenCoefficient = 7154;
const uint32 kBlueCoefficient = 0721;
const uint32 kColorCoefficientDenominator = 10000;
```

Обратите внимание на константу 0721 \(465 в десятичной системе\)\. Ноль явно лишний\. Все коэффициенты: красный, зелёный, синий, — должны в сумме дать 10000\. Но поскольку случайно используется восьмеричное число, значение синего коэффициента будет неверным\.

Другим примером диагностики, реализованной в PVS\-Studio с использованием статистических методов, является [V1071](https://pvs-studio.ru/ru/docs/warnings/v1071/)\. Она предупреждает, что возвращаемое значение функции игнорируется\. При этом в большинстве случаев результат функции каким\-либо образом используется\.

Синтетический пример \(C\+\+\):

```cpp
int foo();
....
auto res = foo();
....
if (foo() == 42) { .... }
....
while (foo() != 42) { .... }
....
return foo();
....
foo();
....
```

Здесь результат функции _foo_ используется четырьмя различными способами, а затем игнорируется в одном из них\. Если результат используется более чем в 90% случаев от общего количества вызовов, анализатор выдаст предупреждение там, где результат не используется\.

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

<details>
   <summary>ГОСТ Р 71207–2024</summary>

[ГОСТ Р 71207–2024](https://pvs-studio.ru/ru/pvs-studio/gost-71207/) определяет статистический анализ как метод статического анализа для поиска дополнительных типов ошибок \(см\. пункт 7\.4\)\. Анализ определяет статистику для некоторого свойства программы, например: насколько часто в программе проверяется возвращаемое значение некоторой функции \(см\. пункт 3\.1\.32\)\.


</details>
**Дополнительные ссылки**

1. Андрей Карпов, Павел Еремеев\. "[Технологии статического анализа кода PVS\-Studio](https://pvs-studio.ru/ru/blog/posts/0908/)"\.
1. Андрей Карпов\. "[Как работает статический анализ?](https://pvs-studio.ru/ru/blog/posts/1048/)"\.
1. Андрей Карпов\. "[Что нельзя найти с помощью статического анализа](https://pvs-studio.ru/ru/blog/posts/1037/)"\.