Sobre/underflow es matemáticamente bien definida de tamaño fijo aritmética de enteros:
(1 - 0xFFFFFFFF) % (1<<32) =
(1 + -0xFFFFFFFF) % (1<<32) =
1 + (-0xFFFFFFFF % (1<<32)) = 2
Este es el resultado correcto!
Específicamente, el resultado después de over/underflow es un alias del entero correcto. De hecho, cada entero no representable tiene un alias (no distinguible) con un entero representable: cuenta hasta el infinito en enteros de tamaño fijo, y se repetirá, dando vueltas y más vueltas como un dial de un reloj analógico.
Un entero de N bits representa cualquier número entero real 2^N. En C, el módulo 2^N se escribe como% (1 < < 32).
Creo que C garantiza la corrección matemática de sobre/bajo flujo, pero solo para enteros sin signo. Se supone que el under/overflow firmado nunca ocurre (en aras de la optimización).
En la práctica, los enteros con signo complementan dos, lo que no hace ninguna diferencia en la suma o la resta, por lo que el comportamiento correcto de sub/desbordamiento está garantizado también para enteros con signo (aunque no por C).
+1 Le doy un puñado de segundos. Buena excavación! – templatetypedef
+1 Guau, yo (obviamente) nunca supe que esta indefinición era parte del estándar. Pero, en este caso, ¿no es 'ptrdiff_t' solo un' signed_t' firmado glorificado? – Mehrdad
@templatetypedef: estoy contento, por una vez, de no despertarme después de la batalla :) @Mehrdad: Yo diría que sí :) Por otro lado, nada prohíbe la implementación de la biblioteca estándar que usas para usar un 64 -bits entero incluso en una plataforma de 32 bits. La norma solo dice que no es obligatorio para ellos hacer el esfuerzo. El resto es un problema de calidad de implementación. –