Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
menu mobile close menu
Проверка проектов
Дополнительная информация
toggle menu Оглавление

V3125. The object was used after it was verified against null. Check lines: N1, N2.

08 Дек 2016

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

Анализатор заметил в коде следующую ситуацию. Сначала объект проверяется на null, а потом используется уже без проверки на null. Это может означать одно из двух:

1) Возникнет исключение, если объект будет равен null.

2) Программа всегда работает корректно, так как объект всегда не равен null. Проверка является лишней.

Рассмотрим первый вариант. Здесь может возникнуть исключение.

obj = Foo();
if (obj != null)
  obj.Func1();
obj.Func2();

Если объект 'obj' окажется равен null, то выражение 'obj.Func2()' приведёт к ошибке. Анализатор выдаст предупреждение на этот код, указав 2 строки. Первая строка - это то место, где используется объект. Вторая строка - это то место, где объект сравнивается со значением null.

Исправленный вариант кода:

obj = Foo();
if (obj != null) {
  obj.Func1();
  obj.Func2();
}

Рассмотрим второй вариант. Проход по списку безопасный, проверка лишняя

List<string> list = CreateNotEmptyList();
if (list == null || list.Count == 0) { .... }
foreach (string item in list) { .... }

Этот код всегда работает корректно. Список list всегда не пуст. Однако анализатор не разобрался в этой ситуации и выдал предупреждение. Чтобы оно исчезло, следует удалить проверку "if (list == null || list.Count == 0)". Она не имеет практического смысла и может только запутать программиста, читающего код.

Исправленный вариант:

List<string> list = CreateNotEmptyList();
foreach (string item in list) { .... }

Ещё один вариант сообщения анализатора - когда проверка и использование расположены в разных ветках if\else или switch выражений. Например:

if (lines.Count == 1)
{
    if (obj != null)
        obj.Func1();
}
else
{
    lines.Clear();
    obj.Func2();
}

В такой ситуации, несмотря на то, что обе ветки никогда не выполнятся одновременно, а будет выбрана только одна из веток, проверка на null в одной из них косвенно свидетельствует о возможности принятия переменной значения null и в другой ветке. Тогда, если управление придёт во вторую ветку, возникнет исключение.

Исправленный вариант:

if (lines.Count == 1)
{
    if (obj != null)
        obj.Func1();
}
else
{
    lines.Clear();
    if (obj != null)
        obj.Func2();
}

В случае если анализатор ошибается, то кроме изменения кода, можно использовать комментарий для подавления предупреждений. Пример: "obj.Foo(); //-V3125".

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

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

Взгляните на примеры ошибок, обнаруженных с помощью диагностики V3125.