Instruções checked e unchecked (referência de C#)
As instruções checked
e unchecked
especificam o contexto de verificação de estouro para operações e conversões aritméticas do tipo integral. Quando ocorre um estouro aritmético inteiro, o contexto de verificação de estouro define o que acontece. Em um contexto verificado, um System.OverflowException é lançado; se o estouro acontece em uma expressão de constante, ocorre um erro em tempo de compilação. Em um contexto não verificado, o resultado da operação é truncado pelo descarte dos bits de ordem superior que não se ajustam ao tipo de destino. Por exemplo, no caso de adição, ele encapsula do valor máximo para o valor mínimo. O seguinte exemplo mostra a mesma operação em um contexto verificado e não verificado:
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.
}
Observação
O comportamento de operadores e conversões definidos pelo usuário no caso do estouro pode ser diferente do descrito no parágrafo anterior. Em particular, os operadores verificados definidos pelo usuário podem não gerar uma exceção em um contexto verificado.
Para obter mais informações, consulte as seções Estouro aritmético e divisão por zero e Operadores verificados definidos pelo usuário do artigo Operadores aritméticos.
Para especificar o contexto de verificação de estouro para uma expressão, você também pode usar os operadores checked
e unchecked
, como mostra o exemplo a seguir:
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.
}
Os operadores e as instruções checked
e unchecked
afetam apenas o contexto de verificação de estouro para as operações que estão textualmente dentro dos parênteses do operador ou do bloco de instrução, como mostra o exemplo a seguir:
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.
}
No exemplo anterior, a primeira invocação da função local Multiply
mostra que a instrução checked
não afeta o contexto de verificação de estouro dentro da função Multiply
, pois nenhuma exceção é gerada. Na segunda invocação da função Multiply
, a expressão que calcula o segundo argumento da função é avaliada em um contexto verificado e resulta em uma exceção, pois está textualmente dentro do bloco da instrução checked
.
Operações afetadas pelo contexto de verificação de estouro
O contexto de verificação de estouro afeta as seguintes operações:
Os seguintes operadores aritméticos internos: operadores
++
,--
,-
unários e+
,-
,*
e/
binários, quando seus operandos são do tipo integral (ou seja, tipo numérico integral ou char) ou um tipo enumerado.Conversões numéricas explícitas entre tipos integrais ou de
float
oudouble
para um tipo integral.Observação
Quando você converte um valor
decimal
em um tipo integral e o resultado está fora do intervalo do tipo de destino, um OverflowException é sempre gerado, independentemente do contexto de verificação de estouro.A partir do C# 11, operadores e conversões verificados definidos pelo usuário. Saiba mais na seção Operadores verificados definidos pelo usuário do artigo Operadores aritméticos.
Contexto de verificação de estouro padrão
Se você não especificar o contexto de verificação de estouro, o valor da opção do compilador CheckForOverflowUnderflow definirá o contexto padrão para expressões não constantes. Por padrão, o valor dessa opção é removido e as conversões e operações aritméticas de tipo integral são executadas em um contexto não verificado.
Expressões constantes são avaliadas por padrão em um contexto verificado e ocorre um erro em tempo de compilação em caso de estouro. Você pode especificar explicitamente um contexto não verificado para uma expressão constante com o operador ou a instrução unchecked
.
Especificação da linguagem C#
Para obter mais informações, confira as seguintes seções da especificação da linguagem C#:
- As instruções marcadas e desmarcadas
- Os operadores verificados e não verificados
- Operadores verificados e não verificados definidos pelo usuário – C# 11