﻿# V104\. Implicit type conversion to memsize type in an arithmetic expression\.


> Это правило входит в группу "Диагностика 64\\\-битных ошибок"\\\. Разработка правил этой группы больше не ведётся, и в будущем они могут быть отключены\\\. Если вы используете эти правила, \[свяжитесь с нашей поддержкой\]\(https://pvs\-studio\.ru/ru/about\-feedback/\) — мы поможем найти замену или предложим альтернативное решение\\\.

Анализатор обнаружил потенциально возможную ошибку внутри арифметического выражения, связанную с неявным приведением к типу memsize\. Ошибка переполнения может быть связана с изменением допустимого интервала значений переменных, входящих в выражение\. 

Первый пример\.

Некорректные выражения сравнения\. Рассмотрим код:

```cpp
size_t n;
unsigned i;
// Infinite loop (n > UINT_MAX).
for (i = 0; i != n; ++i) { ... }
```

В примере показана ошибка, связанная с неявным приведением типа 'unsigned' к типу 'size\_t' при выполнении операции сравнения\.

На 64\-битной платформе у вас может появиться возможность обрабатывать больший объем данных, и значение переменной 'n' может превысить число 'UINT\_MAX' \(4 Гб\)\. В результате, условие "i \!\= n" всегда будет истинно, что приведет к вечному циклу\.

Пример исправленного кода:

```cpp
size_t n;
size_t i;
for (i = 0; i != n; ++i) { ... }
```

Второй пример\.

```cpp
char *begin, *end;
int bufLen, bufCount;
...
ptrdiff_t diff = begin - end + bufLen * bufCount;
```

[Неявное приведение типа](https://pvs-studio.ru/ru/blog/terms/0021/) 'int' к типу 'ptrdiff\_t' зачастую служит признаком ошибки\. Следует обратить внимание, что приведение происходит не при выполнении оператора "\=" \(так как выражение "begin \- end \+ bufLen \* bufCount" имеет тип 'ptrdiff\_t'\), а внутри этого выражения\. Подвыражение "begin \- end" согласно правилам языка С\+\+ имеет тип 'ptrdiff\_t', а правая "bufLen \* bufCount" тип 'int'\. При переходе на 64\-битную платформу программа может начать обрабатывать больший объем данных, в результате чего может произойти переполнение при вычислении подвыражения "bufLen \* bufCount"\.

Следует изменить тип переменных 'bufLen' и 'bufCount' на memsize тип или использовать [явное приведение типа](https://pvs-studio.ru/ru/blog/terms/0015/), как показано на примере:

```cpp
char *begin, *end;
int bufLen, bufCount;
...
ptrdiff_t diff = begin - end + 
  ptrdiff_t(bufLen) * ptrdiff_t(bufCount);
```

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

```cpp
size_t value;
char c1, c2;
size_t result = value + c1 * c2;
```

Анализатор не выдает сообщения, хотя здесь происходит приведение типа 'int' к 'size\_t', так как при вычислении подвыражения "c1 \* c2" переполнения произойти не может\.

Если вы подозреваете в программе наличие ошибок, связанных с некорректным явным приведением типов в выражениях, то Вы можете воспользоваться правилом [V201](https://pvs-studio.ru/ru/docs/warnings/v201/)\. Пример ситуации, при которой явное приведение типа к 'size\_t' скрывает ошибку, представлен ниже:

```cpp
int i;
size_t st;
...
st = size_t(i * i * i) * st;
```

Дополнительные материалы по данной теме:

1. 64\-битные уроки\. Урок 17\. Паттерн 9\. [Смешанная арифметика](https://pvs-studio.ru/ru/blog/lessons/0017/)\.