﻿# V555\. Expression of the 'A \- B \> 0' kind will work as 'A \!\= B'\.

Анализатор обнаружил потенциальную ошибку в выражении вида "A \- B \> 0"\. Высока вероятность, что условие написано неверно, если подвыражение "A \- B" имеет беззнаковый тип\.

Условие "A \- B \> 0" выполняется во всех случаях, когда значение 'A' не равно значению 'B'\. Это значит, что вместо выражения "A \- B \> 0" можно написать "A \!\= B"\. Но скорее всего программист задумывал совсем другое\.

Рассмотрим пример:

```cpp
unsigned int *B;
...
if (B[i]-70 > 0)
```

Программист хотел проверить, что i\-тый элемент массива B больше значения 70\. Это можно было записать так: "B\[i\] \> 70"\. Исходя из каких\-то своих соображений, программист записал эту проверку так: "B\[i\]\-70 \> 0"\. И допустил ошибку\. Он забыл, что элементы массива 'B' имеют тип 'unsigned'\. Это значит, что и выражение "B\[i\]\-70" будет иметь тип 'unsigned'\. Получается, что условие всегда истинно, за исключением случая, когда элемент 'B\[i\]' будет равен 70\.

Поясним эту ситуацию\.

Если 'B\[i\]' больше 70, то "B\[i\]\-70" будет больше 0\.

Если 'B\[i\]' меньше 70, то произойдет переполнение типа unsigned и мы получим очень большое значение\. Пусть B\[i\] \=\= 50\. Тогда "B\[i\]\-70" \= 50u \- 70u \= 0xFFFFFFECu \= 4294967276\. Естественно, что 4294967276 \> 0\.

Демонстрационный пример:

```cpp
unsigned A;
A = 10; cout << "A=10 " << (A-70 > 0) << endl;
A = 70; cout << "A=70 " << (A-70 > 0) << endl;
A = 90; cout << "A=90 " << (A-70 > 0) << endl;
// Будет распечатано
A=10 1
A=70 0
A=90 1
```

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

```cpp
unsigned int *B;
...
if (B[i] > 70)
```

Второй вариант исправленного кода:

```cpp
int *B;
...
if (B[i]-70 > 0)
```

Отметим, что выражение вида "A \- B \> 0" далеко не всегда означает наличие ошибки\. Рассмотрим код, где анализатор выдаст ложное предупреждение:

```cpp
// Функции  GetLength() и GetPosition() возвращают
// значение типа size_t.
while ((inStream.GetLength() - inStream.GetPosition()) > 0)
{ ... }
```

Здесь GetLength\(\) всегда больше или равно GetPosition\(\)\. Поэтому код корректен\. Чтобы избавиться от ложного срабатывания можно использовать комментарий //\-V555 или переписать код следующим образом:

```cpp
while (inStream.GetLength() != inStream.GetPosition())
{ ... }
```

Вот еще один случай, когда ошибки не возникнет\.

```cpp
__int64 A;
__uint32 B;
...
if (A - B > 0)
```

Здесь подвыражение "A \- B" имеет знаковый тип \_\_int64 и ошибки не возникнет\. Анализатор не выдает предупреждения в таких ситуациях\.