V104. Implicit type conversion to memsize type in an arithmetic expression.


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

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

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

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 всегда будет истинно, что приведет к вечному циклу.

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

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

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

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

Неявное приведение типа int к типу ptrdiff_t зачастую служит признаком ошибки. Следует обратить внимание, что приведение происходит не при выполнении оператора "=" (так как выражение begin - end + bufLen * bufCount имеет тип ptrdiff_t), а внутри этого выражения. Подвыражение begin - end согласно правилам языка С++ имеет тип ptrdiff_t, а правая bufLen * bufCount тип int. При переходе на 64-битную платформу программа может начать обрабатывать больший объем данных, в результате чего может произойти переполнение при вычислении подвыражения bufLen * bufCount.

Следует изменить тип переменных bufLen и bufCount на memsize тип или использовать явное приведение типа, как показано на примере:

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

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

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

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

Если вы подозреваете в программе наличие ошибок, связанных с некорректным явным приведением типов в выражениях, то Вы можете воспользоваться правилом V201. Пример ситуации, при которой явное приведение типа к size_t скрывает ошибку, представлен ниже:

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

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


Найденные ошибки

Проверено проектов
346
Собрано ошибок
13 188

А ты совершаешь ошибки в коде?

Проверь с помощью
PVS-Studio

Статический анализ
кода для C, C++, C#
и Java

goto PVS-Studio;