En general, consulte 5/9 en la norma.
En su ejemplo, la firmaron valor se convierte a unsigned (tomándolo UINT_MAX mod + 1), entonces la sustracción se realiza modulo UINT_MAX + 1 para dar un resultado sin signo.
Almacenar este resultado como un valor con signo a s
implica una conversión integral estándar, esto es en 4.7/3. Si el valor está en el rango de signed int
, se conserva; de lo contrario, el valor está definido por la implementación. Todas las implementaciones que he visto alguna vez han usado aritmética de módulo para insertarlo en el rango INT_MIN
a INT_MAX
, aunque como Krit dice, es posible que reciba una advertencia por hacer esto implícitamente.
Las implementaciones de "acrobacias" con las que probablemente nunca tratará podrían tener reglas diferentes para la conversión sin firmar-> firmada. Por ejemplo, si la implementación tiene una representación de signo-magnitud de enteros con signo, entonces no es posible convertir siempre tomando el módulo, ya que no hay forma de representar +/- (UNIT_MAX+1)/2
como int.
También es relevante 5,17/7, "El comportamiento de una expresión de la forma E1 op= E2
es equivalente a E1 = E1 op E2
excepto que E1
se evalúa sólo una vez". Esto significa que para decir que la resta se hace en el tipo unsigned int
, todo lo que necesitamos saber es que s - u
se hace en unsigned int
: no existe una regla especial para -=
que la aritmética se debe hacer en el tipo de LHS.
posible duplicado de [firmado a la conversión sin firmar en C - ¿siempre es seguro?] (Http://stackoverflow.com/questions/50605/signed-to-unsigned-conversion-in-c-is-it-always -seguro) –
No es un duplicado completo. Esa pregunta tenía la última asignación en una variable 'unsigned', por lo que la aritmética es la misma pero la última asignación es diferente. –
También vale la pena mirar: [* ¿Es el comportamiento definido de la resta entera sin signo? *] (Http://stackoverflow.com/q/7221409/1168156) :) – LihO