V1012. The expression is always false. Overflow check is incorrect.


Анализатор обнаружил неправильный способ определения переполнения, которое может возникать при сложении переменных типов 'unsigned short' или переменных типов 'unsigned char'.

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

bool IsValidAddition(unsigned short x, unsigned short y)
{
  if (x + y < x)
    return false;
  return true;
}

При сложении двух переменных типов 'unsigned short', обе переменные приводятся к типу 'int'. Результат сложения также будет иметь тип 'int'. Поэтому, независимо от того, какие значения будут в переменных 'x' и 'y', в результате их сложения переполнения никогда не возникнет. Далее выполняется операция сравнения. При этом правый операнд (переменная 'x') вновь расширяется до типа 'int'. В итоге, приведённый выше код эквивалентен этому:

bool IsValidAddition(unsigned short x, unsigned short y)
{
  if ((int)(x) + (int)(y) < (int)(x))
    return false;
  return true;
}

Получается, что выражение "x + y < x" всегда будет ложно. Вероятнее всего, компилятор оптимизирует функцию, подставив в места ее вызова значение 'true'. Итог: функция ничего на самом деле не проверяет и не защищает от переполнения.

Примечание: Если вы используете модель данных, где размер типа 'short' и типа 'int' совпадают, то такая проверка будет работать корректно и анализатор не будет выдавать предупреждение.

Чтобы получить корректно работающий код, нужно явно выполнить приведение результата сложения к типу 'unsigned short':

if ((unsigned short)(x + y) < x)
{
  ...
}

Согласно Common Weakness Enumeration, потенциальные ошибки, найденные с помощью этой диагностики, классифицируются как CWE-192.


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

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

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

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

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

goto PVS-Studio;