Когда кто-то в комментариях или при разговоре упоминает "статистический анализ кода", то почти наверняка он ошибся/оговорился и имел в виду "статический анализ кода". Однако статистический анализ действительно существует. Он является одним из методов поиска ошибок, используемых статическими анализаторами кода.
Анализатор собирает статистику о некоторых артефактах программного кода и на её основе выявляет аномалии. Рассмотрим, как это может выглядеть на практике.
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.
Однако это очень "жёсткое" правило, чтобы использовать его в обычной практике программирования. Использование восьмеричной константы само по себе не является ошибкой. Более того, иногда восьмеричные константы удобны. В конец концов, не просто так же они появились в языке программирования.
Получается, что просто предупреждать обо всех восьмеричных константах в коде, это плохая идея. С другой стороны, разработчики действительно иногда ошибаются, используя эти константы. Вот здесь на помощь и приходит статистика.
Если в блоке кода используется одиночная восьмеричная константа, то это может быть ошибкой. Если восьмеричных констант несколько, то почти наверняка они используются осознано. Опираясь на эти и некоторые другие критерии, можно выдавать хорошие предупреждения только для некоторых констант.
На этих принципах в анализаторе PVS-Studio устроена диагностика V536. Пример ошибки, найденной с помощью этой диагностики в проекте Chromium (C++):
// 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. Она предупреждает, что возвращаемое значение функции игнорируется. При этом в большинстве случаев результат функции каким-либо образом используется.
Синтетический пример (C++):
int foo();
....
auto res = foo();
....
if (foo() == 42) { .... }
....
while (foo() != 42) { .... }
....
return foo();
....
foo();
....
Здесь результат функции foo используется четырьмя различными способами, а затем игнорируется в одном из них. Если результат используется более чем в 90% случаев от общего количества вызовов, анализатор выдаст предупреждение там, где результат не используется.
То есть анализатор считает странным, когда почти везде результат, который вернула функция, используется, а в отдельных случаях нет.
ГОСТ Р 71207–2024 определяет статистический анализ как метод статического анализа для поиска дополнительных типов ошибок (см. пункт 7.4). Анализ определяет статистику для некоторого свойства программы, например: насколько часто в программе проверяется возвращаемое значение некоторой функции (см. пункт 3.1.32).
Дополнительные ссылки
0