>
>
>
V614. Use of 'Foo' uninitialized variab…


V614. Use of 'Foo' uninitialized variable.

The analyzer has detected use of an uninitialized variable. Using uninitialized variables has unpredictable results. What is dangerous about such defects is that they may hide for years until chance gets suitable values gathered in uninitialized variables.

Consider the following simple example:

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

Whether or not the Foo() function is called depends on a combination of various circumstances. Usually errors of using uninitialized variables occur through misprints. For example, it may appear that a different variable should be used in this place. This is the correct code:

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

It is not only using simple types that the V614 warning is generated. The analyzer may show the warning for variables of the class type which have a constructor and are initialized, as a matter of fact. However, using them without preliminary assignment doesn't have sense. Smart pointers and iterators are examples of such classes.

Have a look at the following samples:

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

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

This is the correct code:

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

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

It happens that the analyzer generates false V614 warnings. But sometimes it happens through the fault of programmers themselves who write tricky code. Have a look at a code sample taken from a real application:

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;
  ....
}

Note that the buffer reading the data from the file is declared as "const void *ptr". For the code to compile, the programmer uses an explicit conversion of the pointer to the type "(void*)". We don't know what made the programmer write this code. The meaningless "const" qualifier confuses the analyzer: it thinks that the _fread() function will use the 'buf' variable only for reading. Since the 'buf' variable is not initialized, the analyzer generates the warning.

The code works, but it cannot be called smart. It should be rewritten: first, it will become shorter and clearer; second, it will stop triggering the V614 warning.

This is the fixed code:

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

There's another situation where V614 may look like a false alarm. Look at the following synthetic example:

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

In this code fragment, the 'Bar' smart pointer of the 'std::shared_ptr' type is created. The default constructor is called for this smart pointer. Thus, 'Bar' is always initialized with 'nullptr'. The analyzer considers it dangerous to use smart pointers created by the default constructor. Still, we can write the code this way. There are several ways to suppress such analyzer warnings.

We can fix the code like this:

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

This code fragment is more readable. We see that the 'GetFoo' function returns an object of the 'std::shared_ptr' type, which contains a null pointer. In this case, a reviewer will expect the 'GetFoo' function to return the null pointer. This code fragment also gives a sign to the analyzer that everything's fine, and the null pointer is returned deliberately.

However, if the analyzer issues a lot of such warnings on the code and you don't want to see them, you can use the following comment:

//-V614_IGNORE_SMART_POINTERS

This comment should be written to the header file included in all other files. For example, "stdafx.h" can be such a file. If you write this comment to the "*.c" or "*.cpp" file, the comment will apply only to this file.

Otherwise, you can suppress false positive warnings.

This diagnostic is classified as:

You can look at examples of errors detected by the V614 diagnostic.