• Empleos
  • Sobre nosotros
  • profesionales
    • Inicio
    • Empleos
    • Cursos y retos
  • empresas
    • Inicio
    • Publicar vacante
    • Nuestro proceso
    • Precios
    • Evaluaciones
    • Nómina
    • Blog
    • Comercial
    • Calculadora de salario

0

529
Vistas
¿Por qué la especificación de C# deja definida la implementación (int.MinValue / -1)?

La expresión int.Minvalue / -1 da como resultado un comportamiento definido por la implementación de acuerdo con la especificación de C#:

7.8.2 Operador de división

Si el operando de la izquierda es el valor entero o largo más pequeño representable y el operando de la derecha es –1, se produce un desbordamiento. En un contexto comprobado, esto provoca que se lance una System.ArithmeticException (o una subclase de la misma). En un contexto no verificado, está definido por la implementación si se lanza una System.ArithmeticException (o una subclase de la misma) o si el desbordamiento no se informa y el valor resultante es el del operando izquierdo.

Programa de prueba:

 var x = int.MinValue; var y = -1; Console.WriteLine(unchecked(x / y));

Esto genera una OverflowException en .NET 4.5 de 32 bits, pero no es necesario.

¿Por qué la especificación deja la implementación del resultado definida? Aquí está el caso en contra de hacer eso:

  1. La instrucción x86 idiv siempre da como resultado una excepción en este caso.
  2. En otras plataformas, podría ser necesaria una comprobación del tiempo de ejecución para emular esto. Pero el costo de ese cheque sería bajo en comparación con el costo de la división. La división de enteros es extremadamente costosa (15-30 ciclos).
  3. Esto abre riesgos de compatibilidad ("escribir una vez, ejecutar en ninguna parte").
  4. Sorpresa del desarrollador.

También es interesante el hecho de que si x / y es una constante de tiempo de compilación, de hecho no se unchecked(int.MinValue / -1) == int.MinValue :

 Console.WriteLine(unchecked(int.MinValue / -1)); //-2147483648

Esto significa que x / y puede tener diferentes comportamientos dependiendo de la forma sintáctica que se use (y no solo dependiendo de los valores de x e y ). Esto está permitido por la especificación, pero parece una elección imprudente. ¿Por qué C# se diseñó así?

Una pregunta similar señala en qué parte de la especificación se prescribe este comportamiento exacto, pero no responde (suficientemente) por qué el lenguaje se diseñó de esta manera. Las opciones alternativas no se discuten.

over 3 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Este es un efecto secundario del hermano mayor de C# Language Specification, Ecma-335 , la especificación Common Language Infrastructure. La Sección III, capítulo 3.31 describe lo que hace el código de operación DIV. Una especificación a la que la especificación C# a menudo tiene que ceder, bastante inevitable. Especifica que puede lanzar pero no lo exige.

De lo contrario, una evaluación realista de lo que hacen los procesadores reales. Y el que todo el mundo usa es el raro. Los procesadores Intel son excesivamente peculiares en cuanto al comportamiento de desbordamiento, fueron diseñados en la década de 1970 con la suposición de que todo el mundo usaría la instrucción INTO. Nadie lo hace, una historia para otro día. Sin embargo, no ignora el desbordamiento en un IDIV y levanta la trampa #DE, no puede ignorar ese fuerte estallido.

Bastante difícil escribir una especificación de idioma además de una especificación de tiempo de ejecución lanosa además de un comportamiento inconsistente del procesador. Poco podía hacer el equipo de C# con eso más que reenviar el lenguaje impreciso. Ya fueron más allá de la especificación al documentar OverflowException en lugar de ArithmeticException. Muy travieso. Tuvieron un vistazo.

Un vistazo que reveló la práctica. Es muy poco probable que sea un problema, el jitter decide si se debe o no en línea. Y la versión no en línea arroja, la expectativa es que la versión en línea también lo haga. Nadie ha sido decepcionado todavía.

over 3 years ago · Santiago Trujillo Denunciar

0

Se dice que uno de los principales objetivos de diseño de C# es la "Ley de sorpresa mínima". De acuerdo con esta guía, el compilador no debe intentar adivinar la intención del programador, sino que debe indicarle al programador que se necesita orientación adicional para especificar correctamente la intención. Esto se aplica al caso de interés porque, dentro de las limitaciones de la aritmética del complemento a dos , la operación genera un resultado muy sorprendente: Int32.MinValue / -1 se evalúa como Int32.MinValue . Se produjo un desbordamiento y se requeriría un bit 33 no disponible, de 0, para representar correctamente el valor correcto de Int32.MaxValue + 1 .

Como se esperaba, y se señaló en su cita, en un contexto verificado, se genera una Excepción para alertar al programador sobre la falla al especificar correctamente la intención. En un contexto no verificado, la implementación puede comportarse como en el contexto verificado o permitir el desbordamiento y devolver el resultado sorprendente. Hay ciertos contextos, como el cambio de bits, en los que es conveniente trabajar con int firmados pero donde el comportamiento de desbordamiento es realmente esperado y deseado. Al consultar las notas de implementación, el programador puede determinar si este comportamiento es realmente el esperado .

over 3 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Nuestro proceso Comercial
Legal
Términos y condiciones Política de privacidad
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recomiéndame algunas ofertas
Necesito ayuda