Предупреждение компилятора (уровень 2) C4146
применение унарного минуса к типу без знака; результат оставлен без знака
Тип без знака может хранить только значения, не являющиеся отрицательными, поэтому унарный минус (отрицание) не имеет смысла при применении к типу без знака. Как операнд, так и результат не являются отрицательными.
На практике это происходит, когда программист пытается выразить минимальное целое значение, которое равно -2147483648. Это значение не может быть записано как -2147483648, поскольку выражение обрабатывается в два этапа:
Число 2147483648 вычисляется. Поскольку оно больше максимального целого значения 2147483647, тип числа 2147483648 не является int, но unsigned int.
Унарный минус применяется к значению с результатом без знака, который также оказывается числом 2147483648.
Тип без знака результата может привести к непредсказуемому поведению. Если результат используется в сравнении, то сравнение без знака может быть использовано, например, когда второй операнд является int. Это объясняет, почему пример программы, представленный ниже, выводит на печать только одну строку.
Ожидаемая вторая строка, 1 is greater than the most negative int, не выводится на печать, поскольку ((unsigned int)1) > 2147483648 имеет значение false.
Вы можете избежать ошибки C4146, используя INT_MIN из limits.h, тип которого — signed int.
Пример
Следующий пример приводит к возникновению ошибки C4146:
// C4146.cpp
// compile with: /W2
#include <stdio.h>
void check(int i)
{
if (i > -2147483648) // C4146
printf_s("%d is greater than the most negative int\n", i);
}
int main()
{
check(-100);
check(1);
}