# V1077. Conditional initialization inside the constructor may leave some members uninitialized.

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

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

    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.

Выявляемые диагностикой ошибки классифицируются согласно ГОСТ Р 71207–2024 как критические и относятся к типу: Ошибки использования неинициализированных переменных.

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

CWE-457