Porównując podpisane z bez znaku, kompilator konwertuje podpisaną wartość na niepodpisaną. Dla równości to nie ma znaczenia -1 == (unsigned) -1
. Dla innych porównań to ważne, na przykład poniższe nie jest prawdą -1 > 2U
.
EDYCJA: Odnośniki:
5/9: (Wyrażenia)
Wiele operatorów binarnych, które oczekują operandów typu arytmetycznego lub wyliczeniowego, powoduje konwersje i zwraca typy wyników w podobny sposób. Celem jest uzyskanie wspólnego typu, będącego jednocześnie typem wyniku. Ten wzorzec nazywa się zwykłymi konwersjami arytmetycznymi, które są zdefiniowane w następujący sposób:
Jeśli jeden z operandów jest typu long double, drugi zostanie przekonwertowany na long double.
W przeciwnym razie, jeśli jeden z operandów jest podwójny, drugi zostanie przekonwertowany na podwójny.
W przeciwnym razie, jeśli jeden z operandów jest zmiennoprzecinkowy, drugi zostanie przekonwertowany na zmiennoprzecinkowy.
W przeciwnym razie promocje całkowe (4.5) będą wykonywane na obu operandach. 54)
Następnie, jeśli jeden z argumentów jest długi bez znaku, drugi zostanie przekonwertowany na długość bez znaku.
W przeciwnym razie, jeśli jeden operand jest typu long int, a drugi int bez znaku, to jeśli long int może reprezentować wszystkie wartości int unsigned int, to unsigned int zostanie przekonwertowany na int long int; w przeciwnym razie oba operandy zostaną przekonwertowane na unsigned long int.
W przeciwnym razie, jeśli jeden z operandów jest długi, drugi zostanie przekształcony w długi.
W przeciwnym razie, jeśli jeden z operandów jest bez znaku, drugi zostanie przekonwertowany na bez znaku.
4.7 / 2: (Integralne konwersje)
Jeśli typ docelowy jest bez znaku, wynikowa wartość jest najmniejszą liczbą całkowitą bez znaku zgodną ze źródłową liczbą całkowitą (modulo 2 n, gdzie n to liczba bitów użytych do reprezentacji typu bez znaku). [Uwaga: W reprezentacji dopełnienia do dwójki ta konwersja jest koncepcyjna i nie ma zmiany we wzorze bitowym (jeśli nie ma obcięcia). ]
EDIT2: poziomy ostrzegawcze MSVC
To, o czym ostrzega się na różnych poziomach ostrzegawczych MSVC, to oczywiście wybory dokonane przez programistów. Jak widzę, ich wybory dotyczące równości ze znakiem / bez znaku w porównaniu z większymi / mniejszymi porównaniami mają sens, jest to oczywiście całkowicie subiektywne:
-1 == -1
oznacza to samo co -1 == (unsigned) -1
- uważam, że wynik jest intuicyjny.
-1 < 2
to nie to samo, co -1 < (unsigned) 2
- Na pierwszy rzut oka jest to mniej intuicyjne, a IMO zasługuje na „wcześniejsze” ostrzeżenie.