¿Por qué estos dos progtwigs se comportaron de manera diferente en ANSI C?

Posible duplicado:
Un enigma (en C)

1.

main() { if(-1<(unsigned char)1) printf("-1 is less than (unsigned char)1:ANSI semantics"); else printf("-1 NOT less than (unsigned char)1:K&R semantics"); } 

2.

 int array[] = {23,41,12,24,52,11}; #define TOTAL_ELEMENTS (sizeof(array)/sizeof(array[0])) main() { int d = -1,x; if(d<=TOTAL_ELEMENTS -2) x = array[d+1]; } 

La primera convierte el carácter 1 sin signo en una variable con signo en ANSI C, mientras que el segundo progtwig convierte d en un int sin signo que hace que la expresión de condición devuelva falso en ANSI C. ¿Por qué se comportaron de manera diferente?

Para el primero, el lado derecho es un char sin signo, y todos los valores de char sin signo se ajustan a un int firmado, por lo que se convierte en int firmado.

Para el segundo, el lado derecho es un int sin signo, por lo que el lado izquierdo se convierte de int firmado a int sin signo.

Consulte también este documento CERT sobre conversiones de enteros .

Starblue explicó la primera parte de tu pregunta. Me quedo con la segunda parte. Debido a que TOTAL_ELEMENTS es un size_t , que no está firmado, el int se convierte a ese tipo sin signo. Your size_t es para que int no pueda representar todos sus valores, por lo que ocurre la conversión de int a size_t , en lugar de size_t a int .

La conversión de números negativos a no firmados está perfectamente definida: el valor se ajusta . Si convierte -1 en un unsigned int , termina en UINT_MAX . Eso es cierto si usas o no el complemento de dos para representar números negativos.

La razón para el documento C tiene más información acerca de ese valor que preserva la conversión.

Así es como recuerdo cómo se aplican las conversiones automáticas:

  • si los tamaños del operando son diferentes, la conversión se aplica al operando más pequeño para que sea del mismo tipo que el operando más grande (con la extensión de signo si el operando más pequeño está firmado)

  • si los operandos son del mismo tamaño, pero uno está firmado y el otro sin firmar, entonces el operando firmado se convierte en sin signo

Si bien lo anterior puede no ser cierto para todas las implementaciones, creo que es correcto para todas las implementaciones de dos complementos.