Udostępnij za pośrednictwem


Ostrzeżenie kompilatora (poziom 2) C4146

jednoargumentowy operator minus zastosowany do typu bez znaku, wynik nadal niepodpisany

Typy niepodpisane mogą przechowywać tylko wartości inne niż ujemne, więc jednoargumentowe minus (negacja) zwykle nie ma sensu w przypadku zastosowania do niepodpisanego typu. Zarówno operand, jak i wynik nie są ujemne.

Uwagi

Gdy wyrażasz literał ujemnej liczby całkowitej, - wartość przed wartością jest analizowana jako jednoargumentowy operator negacji . Kompilator stosuje operator po przeanalizowaniu wartości liczbowej. Jeśli wartość liczbowa pasuje do zakresu niepodpisanej liczby całkowitej, ale nie odpowiadającego mu typu liczby całkowitej ze znakiem, kompilator interpretuje wartość jako niepodpisaną. Niepodpisane wartość jest niezmieniona przez jednoargumentowego operatora negacji.

To ostrzeżenie często występuje podczas próby wyrażenia wartości minimalnej int , -2147483648 lub wartości minimalnej long long -9223372036854775808. Tych wartości nie można zapisać odpowiednio jako -2147483648 lub -9223372036854775808ll. Przyczyną jest to, że kompilator przetwarza wyrażenie w dwóch etapach: najpierw analizuje wartość liczbową, a następnie stosuje operator negacji. Na przykład gdy kompilator analizuje parametr -2147483648, wykonuje następujące kroki:

  1. Obliczana jest liczba 2147483648. Ponieważ jest większa niż maksymalna int wartość 2147483647, ale nadal mieści się w unsigned intobiekcie , typ 2147483648 to unsigned int.

  2. Jednoargumentowy minus jest stosowany do niepodpisanej wartości z niepodpisanym wynikiem, który również ma być 2147483648.

Niepodpisany typ wyniku może spowodować nieoczekiwane zachowanie. Jeśli wynik jest używany w porównaniu, można użyć niepodpisanego porównania, na przykład, gdy drugi operand jest .int

Można uniknąć C4146 za pomocą INT_MIN lub LLONG_MIN z <limits.h> lub odpowiednika języka C++, <climits>. Te wartości mają podpisane typy.

Opcja kompilatora /sdl (Włącz dodatkowe kontrole zabezpieczeń) podnosi to ostrzeżenie do błędu.

Przykład

W poniższym przykładzie pokazano nieoczekiwane zachowanie, które może wystąpić, gdy kompilator generuje ostrzeżenie C4146:

// C4146.cpp
// compile with: /W2
#include <iostream>

void check(int i)
{
    if (i > -9223372036854775808ll)   // C4146
        std::cout << i << " is greater than the most negative long long int.\n";
}

int main()
{
    check(-100);
    check(1);
}

W tym przykładzie kompilator uwzględnia wartość -9223372036854775808ll bez znaku, mimo że literał ma ll sufiks, a operator negacji jest stosowany. Aby porównać<, kompilator dyskretnie promuje podpisany i do .unsigned long long int Oczekiwany drugi wiersz, 1 is greater than the most negative long long int, nie jest drukowany, ponieważ ((unsigned long long int)1) > 9223372036854775808ull ma wartość false.

Aby rozwiązać ten przykład, dołącz <climits> i zmień parametr -9223372036854775808ll na LLONG_MIN.

Zobacz też

Jednoargumentowy operator negacji (-)