﻿# V658\. Value is subtracted from unsigned variable\. It can result in an overflow\. In such a case, the comparison operation may behave unexpectedly\.

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

Выполняются следующие действия:

* из переменной, имеющей беззнаковый тип,  вычитается некоторое значение;
* полученный результат сравнивается с некоторым значением \(используются операторы <, <\=, \>, \>\=\)\.

Если при вычитании возможно переполнение, то результат проверки может отличаться от ожиданий программиста\.

Рассмотрим наиболее простой случай:

```cpp
unsigned A = ...;
int B = ...;
if (A - B > 1)
  Array[A - B] = 'x';
```

Такая проверка по замыслу программиста должна защитить от выхода за границу массива\.  Однако  эта проверка не поможет,  если переменная A < B\.

Пусть: A \= 3, B \= 5;

Тогда: 0x00000003u \- 0x00000005i \= FFFFFFFEu

Выражение "A \- B" согласно правилам языка Си\+\+ имеет тип "unsigned int"\. Значит, "A \- B" будет равно FFFFFFFEu\. Это число больше единицы\. В результате произойдёт обращение к памяти за границей массива\.

Исправить код можно двумя способами\. Во\-первых, вычисления можно производить в переменных знаковых типов:

```cpp
intptr_t A = ...;
intptr_t B = ...;
if (A - B > 1)
  Array[A - B] = 'x';
```

Во\-вторых, можно изменить условие\. Как именно следует изменить условие, зависит от желаемого результата и входных значений\. Если B \>\= 0, то достаточно будет написать:

```cpp
unsigned A = ...;
int B = ...;
if (A > B + 1)
  Array[A - B] = 'x';
```



Если код корректен, то можно отключить вывод диагностического сообщения в данной строке, используя комментарий "//\-V658"\.