Instrucciones activadas y desactivadas (referencia de C#)
Las instrucciones checked
y unchecked
especifican el contexto de comprobación de desbordamiento para conversiones y operaciones aritméticas de tipo integral. Cuando se produce un desbordamiento aritmético de enteros, el contexto de comprobación de desbordamiento define lo que sucede. En un contexto comprobado, se inicia una excepción System.OverflowException; si el desbordamiento tiene lugar en una expresión constante, se produce un error de compilación. En un contexto no comprobado, el resultado de la operación se trunca mediante el descarte de los bits de orden superior que no caben en el tipo de destino. Por ejemplo, la adición se ajusta del valor máximo al valor mínimo. En el ejemplo siguiente se muestra la misma operación en un contexto de comprobación y no comprobación:
uint a = uint.MaxValue;
unchecked
{
Console.WriteLine(a + 3); // output: 2
}
try
{
checked
{
Console.WriteLine(a + 3);
}
}
catch (OverflowException e)
{
Console.WriteLine(e.Message); // output: Arithmetic operation resulted in an overflow.
}
Nota:
El comportamiento de desbordamiento de operadores y conversiones definidos por el usuario puede diferir del descrito en el párrafo anterior. En concreto, es posible que los operadores comprobados definidos por el usuario no inicien una excepción en un contexto comprobado.
Para más información, consulte las secciones Desbordamiento aritmético y división por cero y Operadores comprobados definidos por el usuario del artículo Operadores aritméticos.
Para especificar el contexto de comprobación de desbordamiento de una expresión, también puede usar los operadores checked
y unchecked
, como se muestra en el ejemplo siguiente:
double a = double.MaxValue;
int b = unchecked((int)a);
Console.WriteLine(b); // output: -2147483648
try
{
b = checked((int)a);
}
catch (OverflowException e)
{
Console.WriteLine(e.Message); // output: Arithmetic operation resulted in an overflow.
}
Las instrucciones y los operadores checked
y unchecked
solo afectan al contexto de comprobación de desbordamiento de esas operaciones que están textualmente dentro del bloque de instrucciones o los paréntesis del operador, como se muestra en el ejemplo siguiente:
int Multiply(int a, int b) => a * b;
int factor = 2;
try
{
checked
{
Console.WriteLine(Multiply(factor, int.MaxValue)); // output: -2
}
}
catch (OverflowException e)
{
Console.WriteLine(e.Message);
}
try
{
checked
{
Console.WriteLine(Multiply(factor, factor * int.MaxValue));
}
}
catch (OverflowException e)
{
Console.WriteLine(e.Message); // output: Arithmetic operation resulted in an overflow.
}
En el ejemplo anterior, la primera invocación de la función local Multiply
muestra que la instrucción checked
no afecta al contexto de comprobación de desbordamiento dentro de la función Multiply
, ya que no se produce ninguna excepción. En la segunda invocación de la función Multiply
, la expresión que calcula el segundo argumento de la función se evalúa en un contexto comprobado y da como resultado una excepción, ya que está textualmente dentro del bloque de la instrucción checked
.
El comportamiento de checked
y unchecked
depende del tipo y de la operación. Incluso para enteros, las operaciones como unchecked(x / 0)
siempre se producen porque no hay ningún comportamiento razonable. Compruebe el comportamiento del tipo y la operación para comprender cómo afectan el código y unchecked
las checked
palabras clave.
Tipos numéricos y contexto de comprobación de desbordamiento
Las checked
palabras clave y unchecked
se aplican principalmente a los tipos enteros donde hay un comportamiento de desbordamiento razonable. El comportamiento encapsulado en el que T.MaxValue + 1
se convierte en T.MinValue
razonable en el valor de complemento de dos. El valor representado no es correcto , ya que no puede caber en el almacenamiento del tipo. Por lo tanto, los bits son representativos de los n bits inferiores del resultado completo.
Para tipos como decimal
, float
, double
y Half
que representan un valor más complejo o un valor complementario de uno, la solución de ajuste no es razonable. No se puede usar para calcular resultados más grandes o más precisos, por lo que unchecked
no es beneficioso.
float
, double
y Half
tienen valores de saturación razonables para PositiveInfinity
y NegativeInfinity
, por lo que puede detectar desbordamiento en un unchecked
contexto. Para decimal
, no existen estos límites y la saturación en MaxValue
puede provocar errores o confusión. Las operaciones que usan decimal
inician en un checked
contexto y unchecked
.
Operaciones afectadas por el contexto de comprobación de desbordamiento
El contexto de comprobación de desbordamiento afecta a las siguientes operaciones:
Los siguientes operadores aritméticos integrados: operadores unarios
++
,--
,-
y operadores binarios+
,-
,*
y/
, cuando sus operandos son de tipo entero (es decir, tipo numérico integral o char) o tipo enumeración.Conversiones numéricas explícitas entre tipos enteros o de
float
odouble
a un tipo entero.Nota
Cuando se convierte un valor
decimal
en un tipo entero y el resultado está fuera del intervalo del tipo de destino, siempre se produce una excepción OverflowException, con independencia del contexto de comprobación de desbordamiento.A partir de C# 11, los operadores y conversiones comprobados definidos por el usuario. Para obtener más información, consulte la sección Operadores comprobados definidos por el usuario del artículo Operadores aritméticos.
Contexto de comprobación de desbordamiento predeterminado
Si no especifica el contexto de comprobación de desbordamiento, el valor de la opción del compilador CheckForOverflowUnderflow define el contexto predeterminado para las expresiones noconstantes. De forma predeterminada, el valor de esa opción se anula y se ejecutan operaciones aritméticas de tipo entero en un contexto no comprobado.
Las expresiones constantes se evalúan de forma predeterminada en un contexto comprobado y el desbordamiento produce un error en tiempo de compilación. Puede especificar explícitamente un contexto no comprobado para una expresión constante con la instrucción o el operador unchecked
.
Especificación del lenguaje C#
Para más información, vea las secciones siguientes de la Especificación del lenguaje C#:
- Instrucciones checked y unchecked
- Operadores checked y unchecked
- Operadores comprobados y no comprobados definidos por el usuario: C# 11
Consulte también
- Opción del compilador CheckForOverflowUnderflow