Анализатор обнаружил потенциально возможную ошибку внутри логического условия. Часть логического выражения всегда истинно/ложно и оценено, как подозрительное.
Рассмотрим пример:
uint i = length;
while ((i >= 0) && (n[i] == 0)) i--;
Выражение "i >= 0" всегда истинно, т.к. переменная 'i' имеет тип uint. Поэтому, если значение 'i' дойдёт до нуля, то цикл while не будет остановлен, и 'i' примет максимальное значение типа uint. Попытка дальнейшего доступа к массиву 'n' приведёт к исключению OverflowException.
Корректный код:
int i = length;
while ((i >= 0) && (n[i] == 0)) i--;
Рассмотрим другой пример:
public static double Cos(double d)
{
// -9223372036854775295 <= d <= 9223372036854775295
bool expected = !performCheck ||
!(-9223372036854775295 <= d || // <=
d <= 9223372036854775295);
if (!expected)
....
Программист хотел проверить, что переменная d попадает в заданный диапазон (это видно по комментарию перед проверкой). Но из-за опечатки он написал оператор '||', вместо оператора '&&'. Корректный код:
bool expected = !performCheck ||
!(-9223372036854775295 <= d &&
d <= 9223372036854775295);
Иногда предупреждение V3063 выявляет не ошибку, а просто избыточный код. Рассмотрим пример:
if (@char < 0x20 || @char > 0x7e) {
if (@char > 0x7e
|| (@char >= 0x01 && @char <= 0x08)
|| (@char >= 0x0e && @char <= 0x1f)
|| @char == 0x27
|| @char == 0x2d)
Анализатор предупредит, что подвыражения @char == 0x27 и @char == 0x2d всегда ложны из-за предшествующего оператора if. Этот код может быть вполне корректен. Однако он избыточен, и лучше его упростить. Это сделает программу более простой для понимания другими разработчиками.
Упрощенный вариант кода:
if (@char < 0x20 || @char > 0x7e) {
if (@char > 0x7e
|| (@char >= 0x01 && @char <= 0x08)
|| (@char >= 0x0e && @char <= 0x1f))
Данная диагностика классифицируется как:
Взгляните на примеры ошибок, обнаруженных с помощью диагностики V3063. |