Поделиться через


Предупреждение компилятора (уровень 2) C4146

применение унарного минуса к типу без знака; результат оставлен без знака

Тип без знака может хранить только значения, не являющиеся отрицательными, поэтому унарный минус (отрицание) не имеет смысла при применении к типу без знака. Как операнд, так и результат не являются отрицательными.

На практике это происходит, когда программист пытается выразить минимальное целое значение, которое равно -2147483648. Это значение не может быть записано как -2147483648, поскольку выражение обрабатывается в два этапа:

  1. Число 2147483648 вычисляется. Поскольку оно больше максимального целого значения 2147483647, тип числа 2147483648 не является int, но unsigned int.

  2. Унарный минус применяется к значению с результатом без знака, который также оказывается числом 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);
}