Для получения триального ключа
заполните форму ниже
Team License (базовая версия)
Enterprise License (расширенная версия)
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
GBP
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Мне интересно попробовать плагин на:
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте папку
Spam/Junk и нажмите на письме кнопку "Не спам".
Так Вы не пропустите ответы от нашей команды.

>
>
Так ли хорошо 100% покрытие кода статич…

Так ли хорошо 100% покрытие кода статическим анализом?

29 Авг 2012

Многим кажется, что чем больше выдаст статический анализатор сообщений об ошибках - тем лучше. Это истина, если все сообщения, что называется, попадут в "десятку". Но это невозможно. Одни и те же предупреждения разные программисты в зависимости от типа проекта, могут оценивать как полезные, так и как ложные. Есть и ещё один важный и интересный аспект. Может оказаться, что грань между ложным срабатыванием и настоящей ошибкой очень тонка. Рассмотрим одну из таких ситуаций.

Нами было получено несколько однотипных замечаний от пользователей о ложных срабатываниях анализатора. При изучении присланных примеров кода, встал вопрос о необходимости и целесообразности анализа 100% кода. Ранее такой вопрос никогда не поднимался, так как была уверенность, что чем больше кода проверено, тем лучше.

Было принято решение пересмотреть эту позицию и изменить поведение статического анализатора кода. Рассмотрим один из примеров присланного нам кода:

long adjustment = 0;
long total_weighting = 0;
... //здесь переменная 'total_weighting' не модифицируется
if( total_weighting > 0 )
{
  adjustment /= total_weighting;
}

Возникает неоднозначность. Переменная 'total_weighting' ВСЕГДА равна 0. И нигде не изменяется. Если проверять строчку "adjustment /= total_weighting;", то мы должны выдать сообщение об ошибке "V609 Divide by zero. Denominator 'total_weighting' == 0".

Однако очевидно, что при нулевом значении переменной 'total_weighting' этот код не будет выполнен никогда. Деления на ноль произойти не может.

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

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

int a = 1;
int b = a + 1;

Здесь мы можем быть уверены, что 'b' примет значение равное '2'.

Если в условных операторах существуют логические выражения, гарантировано принимающие значение 'true' или 'false', то принимается соответствующее решение анализировать ветки кода или нет:

  • если значение всегда истинно, то будет проанализирована только 'then' ветка.
  • если значение всегда ложно, то анализируется только 'else' ветка.

Однако в случае невозможности вычислить значение логического выражения в условном операторе будут проанализированы как 'then', так и 'else' ветки.

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

int a = 1;
int b = a + 1;
if (b != 2)
{
  int *p = 0; *p = 1;
}
else
{
  ...
}

Выражение 'b != 2' будет всегда ложно, значит выполнится только 'else' ветка. Соответственно, предупреждение о разыменовании нулевого указателя выдано не будет. Ведь ошибки при выполнении не возникнет.

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


int b = rand() % 10;
if (b != 2)
{
  int *p = 0; *p = 1; //Error!
}
else
{
  ...
}

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

  • Выполнение различных участков кода в зависимости от версии. Пример: if (Version == VERSION_1) ... else if (Version == VERSION_2) ...". Это аналогично использованию конструкций препроцессора #if-#endif, но позволяет быть уверенным, что все ветки кода успешно могут быть компилированы.
  • Комментирование участков кода. Можно быть уверенным, что хотя код не выполняется, он компилируется.
  • Участки кода, используемые при отладке. Во время отладки можно войти внутрь такого кода и сделать что-то полезное. Например, получить доступ к каким-то значениям.
  • Различные действия в зависимости от размеров типов. Пример: if (sizeof(void *) > sizeof(int)).
  • Программирование с использованием макросов.
  • Другие приемы.

Теперь становится ясно, что больше совсем не значит лучше. И анализ 100% кода не может являться показателем качества оценки кода. Избавившись от анализа невыполняемых фрагментов кода, мы получаем меньшее количество сообщений об ошибках, но качество анализа при этом повышается. Важное сообщение об ошибке не затеряется среди ложных сообщений. И при этом число опасных ошибок остается тем же.

Популярные статьи по теме
Бесплатный PVS-Studio для тех, кто развивает открытые проекты

Дата: 22 Дек 2018

Автор: Андрей Карпов

В канун празднования нового 2019 года команда PVS-Studio решила сделать приятный подарок всем контрибьюторам open-source проектов, хостящихся на GitHub, GitLab или Bitbucket. Им предоставляется возмо…
Как и почему статические анализаторы борются с ложными срабатываниями

Дата: 20 Мар 2017

Автор: Андрей Карпов

В своей предыдущей статье я писал, что мне не нравится подход, при котором статические анализаторы кода оцениваются с помощью синтетических тестов. В статье приводился пример, воспринимаемый анализат…
Эффект последней строки

Дата: 31 Май 2014

Автор: Андрей Карпов

Я изучил множество ошибок, возникающих в результате копирования кода. И утверждаю, что чаще всего ошибки допускают в последнем фрагменте однотипного кода. Ранее я не встречал в книгах описания этого …
PVS-Studio для Java

Дата: 17 Янв 2019

Автор: Андрей Карпов

В седьмой версии статического анализатора PVS-Studio мы добавили поддержку языка Java. Пришло время немного рассказать, как мы начинали делать поддержку языка Java, что у нас получилось и какие дальн…
Статический анализ как часть процесса разработки Unreal Engine

Дата: 27 Июн 2017

Автор: Андрей Карпов

Проект Unreal Engine развивается - добавляется новый код и изменятся уже написанный. Неизбежное следствие развития проекта - появление в коде новых ошибок, которые желательно выявлять как можно раньш…
Любите статический анализ кода!

Дата: 16 Окт 2017

Автор: Андрей Карпов

Я в шоке от возможностей статического анализа кода, хотя сам участвую в разработке инструмента PVS-Studio. На днях я был искренне удивлён тому, что анализатор оказался умнее и внимательнее меня.
Технологии, используемые в анализаторе кода PVS-Studio для поиска ошибок и потенциальных уязвимостей

Дата: 21 Ноя 2018

Автор: Андрей Карпов

Краткое описание технологий, используемых в инструменте PVS-Studio, которые позволяют эффективно обнаруживать большое количество паттернов ошибок и потенциальных уязвимостей. Статья описывает реализа…
Зло живёт в функциях сравнения

Дата: 19 Май 2017

Автор: Андрей Карпов

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

Дата: 14 Апр 2016

Автор: Андрей Карпов

Вы угадали, ответ - "42". Здесь приводится 42 рекомендации по программированию, которые помогут избежать множества ошибок, сэкономить время и нервы. Автором рекомендаций выступает Андрей Карпов - тех…
PVS-Studio ROI

Дата: 30 Янв 2019

Автор: Андрей Карпов

Время от времени нам задают вопрос, какую пользу в денежном эквиваленте получит компания от использования анализатора PVS-Studio. Мы решили оформить ответ в виде статьи и привести таблицы, которые по…

Комментарии (0)

Следующие комментарии

На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Этот сайт использует куки и другие технологии, чтобы предоставить вам более персонализированный опыт. Продолжая просмотр страниц нашего веб-сайта, вы принимаете условия использования этих файлов. Если вы не хотите, чтобы ваши данные обрабатывались, пожалуйста, покиньте данный сайт. Подробнее →
Принять