firmado a conversiones sin firmar

Posible duplicado:
Un enigma (en C)

ver este código

#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0])) int array[] = {23,34,12,17,204,99,16}; int main() { int d; for(d=-1;d <= TOTAL_ELEMENTS-2;d++) printf("%d\n",array[d+1]); return 0; } 

ahora este bucle no se ejecutará. sizeof () devolvería un valor sin firmar, por lo que TOTAL_ELEMENTS tiene un valor sin firmar. ahora, llegando al bucle for, dígame si el operador unario ‘-‘ funciona en int firmado 2 o si se realiza una conversión implícita en unsigned y luego el operador ‘-‘ funciona.

En su ejemplo, d se convierte a un int sin signo en la comparación. Pero -1 no se puede representar como un valor int sin signo , por lo que se convierte a UINT_ MAX. Para evitar este comportamiento, puede convertir el lado derecho de la comparación a un int firmado por prepending (int) .

Consulte Comprender las reglas de conversión de enteros para obtener detalles sobre la conversión de enteros en C.

No hay operador unario en d <= TOTAL_ELEMENTS-2.

TOTAL_ELEMENTS-2 se reduce a una expresión con un operador binario de -. Esta expresión se convierte en sin signo porque uno de sus operandos no está firmado.

En el caso de d <= TOTAL_ELEMENTS-2, el tipo d también se convierte a int sin signo por el mismo motivo.

La parte relevante de la norma es la sección 6.3.1.8 # 1 (ISO / IEC 9899: 1999) que dice:

“De lo contrario, si el operando que tiene un tipo entero sin signo tiene un rango mayor o igual al rango del tipo del otro operando, entonces el operando con tipo entero con signo se convierte al tipo del operando con tipo entero sin signo”.

Sí, d también tiene un tipo sin signo en esa expresión, debido a la promoción, razón por la cual el bucle falla.

Sin embargo, la pregunta es si el comstackdor de C “piensa”:

(unsigned) ((unsigned) 5 - (unsigned) 2)

es decir, promoviendo 2 a unsigned, o

(unsigned) ((unsigned) 5 - (signed) 2)

Es decir, resta tomando operandos de ambos tipos. Por supuesto, no importa, ya que sería la misma operación para ambos. Sin embargo, todo el punto es que restar devolverá un valor de un tipo, por lo que en teoría solo puede tomar argumentos de ese tipo. Así que es el primero (unsigned int 2).

PS (-2) es unario, mientras que (5 – 2) es binario.

Sospecho que el tipo sin signo de sizeof() propaga a la expresión TOTAL_ELEMENTS-2 y luego a ambos operandos de d <= TOTAL_ELEMENTS-2 . Insertar (int) juste antes de TOTAL_ELEMENTS soluciona el problema.

mira, ese operador ‘-‘ ser unario era una cosa estúpida. olvídalo. era el binario ‘-‘, me doy cuenta.

cuando 2 se convierte a int sin signo, se convierte en 2 sin signo, por lo que TOTAL_ELEMENTS-2 tiene un valor igual a 5 sin signo, y luego, cuando d se convierte a un int sin signo, obtiene un gran valor positivo y
por lo que el bucle falla.

¿Eso está pasando aquí?

y sí, no escribí este código, este es un rompecabezas que encontré en la web. gracias a todos