¿El desbordamiento de enteros con signo sigue siendo un comportamiento indefinido en C++?

Resuelto Archie asked hace 11 años • 3 respuestas

Como sabemos, el desbordamiento de enteros con signo es un comportamiento indefinido . Pero hay algo interesante en cstdintla documentación de C++11:

tipo entero con signo con un ancho de exactamente 8, 16, 32 y 64 bits respectivamente, sin bits de relleno y usando complemento a 2 para valores negativos (proporcionado solo si la implementación admite directamente el tipo)

Ver enlace

Y aquí está mi pregunta: dado que el estándar dice explícitamente que para int8_t, y los números negativos son complemento a 2, ¿sigue siendo el desbordamiento de estos tipos un comportamiento indefinido?int16_tint32_tint64_t

Editar Revisé los estándares C++11 y C11 y esto es lo que encontré:

C++11, §18.4.1:

El encabezado define todas las funciones, tipos y macros igual que 7.20 en el estándar C.

C11, §7.20.1.1:

El nombre typedef intN_tdesigna un tipo entero con signo con ancho N, sin bits de relleno y una representación en complemento a dos. Por lo tanto, int8_tdenota un tipo entero con signo con un ancho de exactamente 8 bits.

Archie avatar Apr 24 '13 16:04 Archie
Aceptado

¿Sigue siendo el desbordamiento de estos tipos un comportamiento indefinido?

Sí. Según el párrafo 5/4 del estándar C++11 (con respecto a cualquier expresión en general):

Si durante la evaluación de una expresión, el resultado no está definido matemáticamente o no está en el rango de valores representables para su tipo, el comportamiento es indefinido . [...]

El hecho de que se utilice una representación en complemento a dos para esos tipos con signo no significa que se utilice módulo aritmético 2^n al evaluar expresiones de esos tipos.

En cuanto a la aritmética sin signo , por otra parte, la Norma especifica explícitamente que (Párrafo 3.9.1/4):

Los enteros sin signo, declarados unsigned, obedecerán las leyes de la aritmética módulo 2^n donde n es el número de bits en la representación del valor de ese tamaño particular de entero.

Esto significa que el resultado de una operación aritmética sin signo siempre está " definido matemáticamente " y el resultado siempre está dentro del rango representable; por lo tanto, 5/4 no se aplica. La nota a pie de página 46 explica esto:

46) Esto implica que la aritmética sin signo no se desborda porque un resultado que no puede representarse mediante el tipo entero sin signo resultante se reduce en módulo el número que es uno mayor que el valor más grande que puede representarse mediante el tipo entero sin signo resultante.

Andy Prowl avatar Apr 24 '2013 09:04 Andy Prowl

El hecho de que un tipo esté definido para utilizar la representación en complemento a 2 no significa que se defina el desbordamiento aritmético en ese tipo.

El comportamiento indefinido del desbordamiento aritmético con signo se utiliza para permitir optimizaciones; por ejemplo, el compilador puede asumir que si a > bentonces a + 1 > btambién; esto no se cumple en la aritmética sin signo donde sería necesario realizar la segunda verificación debido a la posibilidad de que a + 1podría llegar a 0. Además, algunas plataformas pueden generar una señal trampa en caso de desbordamiento aritmético (consulte, por ejemplo, http://www.gnu.org/software/libc/manual/html_node/Program-Error-Signals.html ); la norma continúa permitiendo que esto ocurra.

ecatmur avatar Apr 24 '2013 09:04 ecatmur