# V3022. Expression is always true/false.

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

Пример кода:

    string niceUrl = GetUrl();
    if (niceUrl != "#" || niceUrl != "") {
        Process(niceUrl);
    } else {
        HandleError();
    }

Анализатор выдает предупреждение:

"V3022 Expression 'niceUrl != "#" || niceUrl != ""' is always true. Probably the '&&' operator should be used here. "

Здесь ветка else никогда не будет выполнена. Дело в том, что какое бы значение ни приняла переменная niceUrl, одно из сравнений со строкой всегда будет истинно. Чтобы исправить эту ошибку, следует использовать оператор && вместо оператора ||. Корректный вариант кода:

    string niceUrl = GetUrl();
    if (niceUrl != "#" && niceUrl != "") {
        Process(niceUrl);
    } else {
        HandleError();
    }

Теперь рассмотрим пример кода, в котором имеется бессмысленное сравнение. Возможно этот код не является ошибочным, но на него обязательно следует обратить внимание:

    byte type = reader.ReadByte();
    if (type < 0)
        recordType = RecordType.DocumentEnd;
    else
        recordType = GetRecordType(type);

Ошибка заключается в сравнении переменной беззнакового типа с нулём. Данный фрагмент кода будет диагностирован так: "V3022 Expression 'type < 0' is always false. Unsigned type value is always >= 0.". В этом примере либо сравнение лишнее, либо случай достижения конца документа обработан неправильно.

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

    // 1) Временно убранный из компиляции блок кода
    if (false && CheckCondition())
    {
    ...
    }

    // 2) Выражения внутри Debug.Assert()
    public enum Actions { None, Start, Stop }
    ...
    Debug.Assert(Actions.Start > 0);

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

CWE-570 CWE-571

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