V730. Not all members of a class are initialized inside the constructor.
The analyzer has detected a constructor that doesn't initialize some of the class members.
Here's a simple synthetic example:
struct MyPoint
{
int m_x, m_y;
MyPoint() { m_x = 0; }
void Print() { cout << m_x << " " << m_y; }
};
MyPoint Point;
Point.Print();
When creating the Point object, a constructor will be called that won't initialize the 'm_y' member. Accordingly, when calling the Print function, an uninitialized variable will be used. The consequences of this are unpredictable.
The correct version of the constructor should look like this:
MyPoint() { m_x = 0; m_y = 0; }
We have discussed a simple synthetic example, where a bug can be easily spotted. However, in real-life code, things may be much more complicated. Search of uninitialized class members is implemented through a set of empirical algorithms. Firstly, class members can be initialized in a large variety of ways, and it's sometimes difficult for the analyzer to figure out whether or not a class member has been initialized. Secondly, not all the members should be initialized all the time, and the analyzer may output false positive warnings as it doesn't know the programmer's intentions.
Search of uninitialized class members is a difficult and thankless task. This matter is discussed in more detail in the article "In search of uninitialized class members". So please be understanding when you get false positives and use the false positive suppression mechanisms the analyzer provides.
You can suppress a warning by marking the constructor with the comment "//-V730". Another way is to use a special database for false positives. As a last resort, when there are too many of them, consider disabling the V730 diagnostic altogether.
But these are extreme measures. In practice, it might make sense to exclude from analysis individual structure members that don't need to be initialized in the constructor. Here's another synthetic example:
const size_t MAX_STACK_SIZE = 100;
class Stack
{
size_t m_size;
int m_array[MAX_STACK_SIZE];
public:
Stack() : m_size(0) {}
void Push(int value)
{
if (m_size == MAX_STACK_SIZE)
throw std::exception("overflow");
m_array[m_size++] = value;
}
int Pop()
{
if (m_size == 0)
throw std::exception("underflow");
return m_array[--m_size];
}
};
This class implements a stack. The 'm_array' array is not initialized in the constructor, and that's correct because the stack is considered originally empty.
The analyzer will output warning V730 as it can't figure out how this class works. You can help it by marking the 'm_array' member with the comment "//-V730_NOINIT" to specify that the 'm_array' array doesn't need to be necessarily initialized.
From that point on, the analyzer won't produce the warning when analyzing this code:
class Stack
{
size_t m_size;
int m_array[MAX_STACK_SIZE]; //-V730_NOINIT
public:
Stack() : m_size(0) {}
.....
};
There is a way to disable V730 warnings for all class fields of a certain type.
Let's consider the example:
class Field
{
public:
int f;
};
class Test
{
public:
Test() {}
Field field;
};
The following warning will be issued for this code fragment: V730 Not all members of a class are initialized inside the constructor. Consider inspecting: field.
To exclude all warnings of a class field of the type 'Field', one has to add the following comment in the code or settings file:
//+V730:SUPPRESS_FIELD_TYPE, class:Field
The format of the comment:
//+V730:SUPPRESS_FIELD_TYPE, class:className, namespace:nsName
or
//+V730:SUPPRESS_FIELD_TYPE, class:className.NestedClassName, namespace:nsName
This diagnostic is classified as:
|
You can look at examples of errors detected by the V730 diagnostic. |