Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
jednoargumentowy operator minus zastosowany do typu bez znaku, wynik nadal niepodpisany
Uwagi
Typy niepodpisane przechowują tylko wartości inne niż ujemne. Dlatego jednoargumentowy minus (negacja) zwykle nie ma sensu w przypadku zastosowania do niepodpisanego typu. Zarówno operand, jak i wynik nie są ujemne.
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ą.
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ć jako -2147483648 ani -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:
- Obliczana jest liczba 2147483648. Ponieważ jest większa niż maksymalna
intwartość 2147483647, ale nadal mieści się wunsigned intobiekcie , typ 2147483648 tounsigned int. - 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.