El lenguaje C realiza las "conversiones aritméticas habituales" para muchos operadores - la las conversiones se describen en 6.3.1.8 del estándar C99. Para operandos integrales, se realizan las primeras promociones, y esto es lo que está causando su problema. Las promociones se describen en 6.3.1.1 (operandos aritméticos/booleanas, personajes y enteros), que dice entre otras cosas:
Si un int puede representar todos los valores del tipo original, el valor se convierte en una En t; de lo contrario, se convierte a unsigned int. Estas se llaman promociones enteras. Todos los otros tipos no se modifican por las promociones enteras.
Las promociones sólo se aplican a los objetos o expresiones con un tipo entero con un rango de menos de int
y unsigned int
(o campos de bits).
Así que en su exression:
t1 < t2-1
a pesar de que las variables son unsigned short
son promovidos a int, ya que en su plataforma int
puede representar todos los valores de unsigned short
. Por lo tanto, la expresión se evalúa utilizando los tipos int
, y no se produce subdesbordamiento - la parte t2-1
de la expresión termina como negativa 1.
En la expresión:
s1 < s2-1
los tipos unsigned long
no se promueven, porque tienen un mayor 'ranking' de int
/unsigned int
, por lo que la expresión se evalúa usando aritmética sin signo (con la corriente de fondo de la resta), y la s2-1
sub-expresión se evalúa como un número muy grande, no es negativo 1.
como litb se indica en un comentario, si la plataforma había int
implementado como un tipo de 16 bits (lo cual está permitido - MS-DOS para ejemplo), el profesional el movimiento de unsigned short
sería unsigned int
en lugar de int
, ya que un int
no podría representar todos los valores de unsigned short
(unsigned short
debe ser de al menos 16 bits). En ese caso, ambas declaraciones if
se evaluarían como verdaderas.
~ nairboon: Espero que no te importe la edición. El código con el que reemplacé el suyo es funcionalmente el mismo, pero se puede copiar/pegar en un editor y compilar sin cambios. –
Tenga en cuenta que no se garantiza que este resultado sea el resultado. En las máquinas donde int almacena el mismo rango de valores que corto (creo que máquinas de 16 bits), verá salida para ambos ifs, porque la promoción se convertirá a unsigned int entonces, en lugar de a int. –