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

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

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

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

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

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

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


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

>
>
>
V614. Use of 'Foo' uninitialized variab…
Проверка проектов
Сообщения PVS-Studio
Диагностики общего назначения (General Analysis, C++)
Диагностики общего назначения (General Analysis, C#)
Диагностики общего назначения (General Analysis, Java)
Диагностика микро-оптимизаций (C++)
Диагностика 64-битных ошибок (Viva64, C++)
Реализовано по запросам пользователей (C++)
Cтандарт MISRA
Стандарт AUTOSAR
Стандарт OWASP (C#)
Проблемы при работе анализатора кода
Дополнительная информация
Оглавление

V614. Use of 'Foo' uninitialized variable.

09 Ноя 2012

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

Рассмотрим простейший пример:

int Aa = Get();
int Ab;
if (Ab) // Ab - uninitialized variable
  Ab = Foo();
else
  Ab = 0;

Будет или нет вызвана функция Foo(), зависит от стечения различных обстоятельств. Как правило, ошибки использования неинициализированных переменных, возникают из-за опечаток. Например, может оказаться, что в этом месте следовало использовать другую переменную. Корректный вариант кода:

int Aa = Get();
int Ab;
if (Aa) // OK
  Ab = Foo();
else
  Ab = 0;

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

Рассмотрим примеры:

std::auto_ptr<CLASS> ptr;
UsePtr(ptr);

std::list<T>::iterator it;
*it = X;

Корректный вариант кода:

std::auto_ptr<CLASS> ptr(Get());
UsePtr(ptr);

std::list<T>::iterator it;
it = Get();
*it = X;

Бывает, что анализатор выдаёт ложные сообщения V614. Но иногда в этом виноват сам программист, написавший коварный код. Рассмотрим пример кода, взятый из реального приложения:

virtual size_t _fread(const void *ptr, size_t bytes){
  size_t ret = ::fread((void*)ptr, 1, bytes, fp);
  if(ret < bytes)
    failbit = true;
  return ret;
}

int read32le(uint32 *Bufo, EMUFILE *fp)
{
  uint32 buf;
  if(fp->_fread(&buf,4)<4)   //  False alarm: V614
    return 0;
  ....
}

Обратите внимание, что буфер, куда читаются данные из файла, объявлен как "const void *ptr". Чтобы код компилировался, используется явное приведение указателя к типу "(void*)". Неизвестно, что побудило программиста написать такой код. Бессмысленный квалификатор "const" путает анализатор. Анализатор считает, что функция _fread() будет использовать переменную 'buf' только для чтения. Так как переменная 'buf' не инициализирована, анализатор выдаёт предупреждение.

Этот код работает. Однако его нельзя назвать хорошим. Рационально будет его переписать. Во-первых, код станет короче и понятней. Во-вторых, исчезнет предупреждение V614.

Исправленный вариант кода:

virtual size_t _fread(void *ptr, size_t bytes){
  size_t ret = ::fread(ptr, 1, bytes, fp);
  if(ret < bytes)
    failbit = true;
  return ret;
}

Есть ещё одна ситуация, когда предупреждение V614 может показаться ложным. Рассмотрим следующий синтетический пример:

std::shared_ptr<foo> GetFoo()
{
  std::shared_ptr<foo> Bar;
  return Bar;                        // V614
}

Здесь создается умный указатель 'Bar' типа 'std::shared_ptr', для которого будет вызван конструктор по умолчанию. Поэтому 'Bar' всегда будет инициализирован 'nullptr'. Анализатор считает опасным использование умных указателей, созданных конструктором по умолчанию. Тем не менее, такой код имеет право на жизнь. Есть несколько способов убрать подобные предупреждения анализатора.

Можно поправить код следующим образом:

std::shared_ptr<foo> GetFoo()
{
  std::shared_ptr<foo> Bar { nullptr };
  return Bar;                           // no V614
}

Такой код лучше читается, потому что теперь сразу понятно, что функция 'GetFoo' возвращает объект типа 'std::shared_ptr', содержащий нулевой указатель. В этом случае ревьюверу будет более очевидно, что предполагается именно нулевой указатель. Такая запись также является знаком анализатору, что программист знает, что он делает, и нулевой указатель возвращается осознанно, а не по ошибке.

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

//-V614_IGNORE_SMART_POINTERS

Этот комментарий следует вписать в заголовочный файл, который включается во все другие файлы. Например, таким файлом может быть "stdafx.h". Если вписать этот комментарий в "*.с" или "*.cpp" файл, то он будет действовать только для этого файла.

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

Данная диагностика классифицируется как:

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

Unicorn with delicious cookie
Мы используем куки, чтобы пользоваться сайтом было удобно. Хотите узнать подробнее?
Принять