Анализатор обнаружил потенциальную ошибку в выражении вида "A - B > 0". Высока вероятность, что условие написано неверно, если подвыражение "A - B" имеет беззнаковый тип.
Условие "A - B > 0" выполняется во всех случаях, когда значение 'A' не равно значению 'B'. Это значит, что вместо выражения "A - B > 0" можно написать "A != B". Но скорее всего программист задумывал совсем другое.
Рассмотрим пример:
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.
Демонстрационный пример:
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
Первый вариант исправленного кода:
unsigned int *B; ... if (B[i] > 70)
Второй вариант исправленного кода:
int *B; ... if (B[i]-70 > 0)
Отметим, что выражение вида "A - B > 0" далеко не всегда означает наличие ошибки. Рассмотрим код, где анализатор выдаст ложное предупреждение:
// Функции GetLength() и GetPosition() возвращают // значение типа size_t. while ((inStream.GetLength() - inStream.GetPosition()) > 0) { ... }
Здесь GetLength() всегда больше или равно GetPosition(). Поэтому код корректен. Чтобы избавиться от ложного срабатывания можно использовать комментарий //-V555 или переписать код следующим образом:
while (inStream.GetLength() != inStream.GetPosition()) { ... }
Вот еще один случай, когда ошибки не возникнет.
__int64 A; __uint32 B; ... if (A - B > 0)
Здесь подвыражение "A - B" имеет знаковый тип __int64 и ошибки не возникнет. Анализатор не выдает предупреждения в таких ситуациях.
Данная диагностика классифицируется как:
|
Взгляните на примеры ошибок, обнаруженных с помощью диагностики V555. |