>
>
>
V1077. Constructor contains potentially…


V1077. Constructor contains potentially uninitialized members.

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

Рассмотрим простой синтетический пример:

struct Cat 
{
  int age;

  Cat(bool isKitten)
  {
    if (isKitten)
    {
      age = 3;
    }
  }
};

Если при конструировании объекта типа 'Cat' в качестве фактического параметра будет передано значение 'false', то нестатическое поле класса 'age' не будет проинициализировано. Последующий доступ к этому полю приведет к неопределённому поведению:

#include <iostream>

void Cat()
{
  Cat instance { false };
  std::cout << instance.x << std::endl; // UB 
}

Корректный конструктор может выглядеть следующим образом:

Cat(bool isKitten) : age { 0 }
{
  if (isKitten)
  {
    age = 3;
  }
}

Если допускается, что какой-либо член класса может остаться неинициализированным после выполнения конструктора, то можно подавить для них предупреждения специальным комментарием "//-V1077_NOINIT":

struct Cat
{
  int age; //-V1077_NOINIT

  Cat(bool isKitten)
  {
    if (isKitten)
    {
      age = 3;       // ok
    }
  }
};

Вы можете подавить предупреждение, отметив конструктор комментарием "//-V1077". Вы также можете применить механизм массового подавления для устранения ложных срабатываний.

Диагностика также поддерживает возможность отключить предупреждения на все поля классов определенного типа. Для этого используется тот же комментарий, что и в диагностике V730 (поиск неинициализированных членов класса в конструкторах).

Рассмотрим формат комментария:

//+V730:SUPPRESS_FIELD_TYPE, class:className, namespace:nsName

Если указать в качестве аргумента параметра 'class' класс с названием 'className', то поля этого типа будут рассматриваться как исключения в диагностике V1077 и V730. Рассмотрим пример:

//+V730:SUPPRESS_FIELD_TYPE, class:Field

struct Field
{
  int f;
};

class Test
{
  Field someField;

public:
  Test(bool cond, int someValue) 
  {
    if (cond)
    {
      someField.f = someValue; // ok
    }
  }
};

При указании специального комментария анализатор не будет выдавать предупреждение на поля, имеющие тип 'Field' ('someField' в нашем случае).

Для вложенных классов используется следующий синтаксис:

//+V730:SUPPRESS_FIELD_TYPE, class:className.NestedClassName,
  namespace:nsName

Каждый вложенный класс отделяется точкой: "className.NestedClassName".

Мы не стали вводить отдельный комментарий для V1077 по следующим причинам. Если тип отмечен комментарием для V730, значит предполагается, что его экземпляры могут быть не проинициализированы вообще, а значит выдавать для него V1077 тоже бессмысленно. К тому же, если у вас уже есть разметка для V730, она будет работать и для V1077.

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