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

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

Бесплатная лицензия PVS-Studio для специалистов Microsoft MVP
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

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

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

Ваше сообщение отправлено.

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


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

>
>
>
Пояснение про диагностику V595

Пояснение про диагностику V595

26 Окт 2015

В анализаторе PVS-Studio существует диагностика V595 "The pointer was utilized before it was verified against nullptr". Я получаю много вопросов от наших пользователей, которые касаются как раз этой диагностики. Поэтому я решил заранее подготовить обстоятельный ответ, который поможет мне в дальнейшем объяснять, как работает эта диагностика.

Описание диагностики V595 в документации: The pointer was utilized before it was verified against nullptr.

Примечание. С момента написания статьи в 2015 году многое изменилось, и диагностика V595 стала более интеллектуальной. Теперь анализатор умеет заглядывать в тела функций, в том числе расположенных в разных файлах. Благодаря этому могут быть обнаружены более сложные варианты ошибок. См. раздел "Технология статического анализа кода PVS-Studio".

Типовой вопрос, касающийся V595, звучит следующим образом:

У меня есть код следующего вида:

void MyClass::Do()
{
  m_ptr->Foo(1, 2, 3);
  Process(1, 2, 3, 4, 5);
}

Член класса 'm_ptr' иногда может принимать нулевые значения. В результате, происходит падание программы. Я ожидал, что анализатор PVS-Studio выдаст предупреждение, что указатель 'm_ptr' следует проверить перед использование. Я хочу увидеть предупреждение V595, а его нет. Прошу пояснить эту ситуацию.

Постараюсь дать подробный ответ.

Анализатор PVS-Studio в общем случае не диагностирует ситуацию, что указатель может быть нулевой и перед использованием его следует проверить.

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

Идеологически правильно пытаться понять, может ли указатель принимать нулевое значение. Это невероятно сложная техническая задача. Нужно анализировать call graph и пытаться понять возможные значения переменных. На практике, это невозможно. Различные анализаторы, и PVS-Studio в их числе, пытаются частично решать эту задачу для простых случаев. Но в целом все равно получается плохо. Многие ошибки не будут замечены, многие пропущены.

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

void Foo(int *p)
{
  if (!p)
  {
    p[1] = 2; //V522
  }
}

Анализатор видит, что мы входим в тело if, если указатель равен 0. Значит разыменование указателя приведёт к ошибке. Это очень простой пример. В сложных вариантах, например, как в первом примере, анализатор бессилен. Он не может вычислить, что лежит в 'm_ptr' в данный момент.

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

Поясню на примере. Здесь PVS-Studio не знает, что будет в 'p' и поэтому ему нечего сказать:

void Foo()
{
  int *p = Get();
  p[0] = 1;
  ....
}

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

void Foo()
{
  int *p = Get();
  p[0] = 1; // V595
  ....
  if (p == NULL)
    Zzz();
}

PVS-Studio выдаёт предупреждение V595. Анализатор не способен вычислить, что вернёт функция Get(). Но ему это и не нужно. Он видит, что ниже указатель проверятся на равенство нулю. Это значит, что возможны ситуации, когда указатель нулевой. И разыменовывать его без проверки нельзя.

Надеюсь я пояснил как работает анализатор и почему анализатор не выдаёт предупреждение для кода показанного в самом начале. Ниже нет проверки, что переменная 'm_ptr' равна 0, поэтому нет и предупреждения. К сожалению, анализатор здесь бессилен.

Популярные статьи по теме
Как различить C и C++ разработчиков по их коду

Дата: 12 Май 2022

Автор: Гость

Так уж случилось, что я пишу код для разных IoT-железок, связанных с электричеством, типа зарядных станций автомобилей. Поскольку аппаратных ресурсов, как правило, вполне достаточно, то основным фоку…
Отладочный вывод на микроконтроллерах: как Concepts и Ranges отправили мой printf на покой

Дата: 06 Май 2022

Автор: Гость

Здравствуйте! Меня зовут Александр, и я работаю программистом микроконтроллеров.
Нереальный baselining или доработки PVS-Studio для Unreal Engine проектов

Дата: 26 Апр 2022

Автор: Валерий Комаров

Статический анализатор PVS-Studio постоянно развивается: улучшаются различные механизмы, происходит интеграция с игровыми движками, IDE, CI/CD и другими системами и сервисами. Благодаря этому несколь…
Разбор некоторых вредных советов для С++ программиста

Дата: 21 Апр 2022

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

Юмор юмором, но осторожность не повредит. Вдруг кому-то не до конца понятно, почему какой-то из советов является вредным. Здесь можно найти соответствующие пояснения.
Четыре причины проверять, что вернула функция malloc

Дата: 20 Апр 2022

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

Некоторые разработчики пренебрежительно относятся к проверкам: удалось ли выделить память с помощью функции malloc или нет. Их логика проста – памяти всегда должно хватить. А если не хватит, всё равн…

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

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