Język C wykonuje „Powszechna arytmetycznych konwersje” Dla wielu podmiotów - w Konwersje są opisane w 6.3.1.8 standardu C99. W przypadku operandów zintegrowanych wykonywane są pierwsze promocje i to właśnie jest przyczyną problemu. Te promocje są opisane w 6.3.1.1 (arytmetyczne argumenty/logiczne, znaków i liczb całkowitych), który mówi między innymi:
Jeśli int może reprezentować wszystkie wartości tego samego typu, wartość jest konwertowana na int; w przeciwnym razie jest konwertowany na unsigned int. Są to tak zwane promocje bezpośrednie. Wszystkie pozostałe typy są niezmienione przez promocje całkowite.
W promocji są stosowane wyłącznie do obiektów lub wyrażenia z typem całkowitą z szeregu mniej niż int
i unsigned int
(lub bitfields).
Więc w exression:
t1 < t2-1
chociaż zmienne są unsigned short
są promowane na int, ponieważ na platformie int
może reprezentować wszystkie wartości z unsigned short
. Tak więc wyrażenie jest oceniane przy użyciu typów int
i nie występuje niedopełnienie - część wyrażenia kończy się jako ujemna 1.
W wyrażeniu:
s1 < s2-1
rodzaje unsigned long
nie są promowane, ponieważ mają wyższą rangę „” niż int
/unsigned int
, więc wyrażenie jest oceniane przy użyciu arytmetyki bez znaku (z dolnego z odejmowanie) oraz s2-1
podwyrażenie ocenia bardzo dużej liczby, nie negatywnym 1.
jak litb wskazano w komentarzu, jeśli platforma nie int
zaimplementowany jako typ 16-bitowy (co jest dozwolone - dla systemu MS-DOS przykład), pro ruch unsigned short
byłby następujący: unsigned int
zamiast int
, ponieważ int
nie byłby w stanie reprezentować wszystkich wartości unsigned short
(unsigned short
musi mieć co najmniej 16 bitów). W takim przypadku oba oświadczenia będą miały wartość true.
~ nairboon: Mam nadzieję, że nie masz nic przeciwko edycji. Kod, który zastąpiłem twój jest funkcjonalnie taki sam, ale można go skopiować/wkleić do edytora i skompilować bez zmian. –
Należy pamiętać, że wynik ten nie jest gwarantowany. Na komputerach, na których int przechowuje ten sam zakres wartości, co krótki (wydaje się, że 16-bitowe komputery), zobaczysz dane wyjściowe dla obu znaków ifs, ponieważ promocja zamieni się wtedy na unsigned int, zamiast na int. –