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