Istruzioni checked e unchecked (Riferimenti per C#)
Le istruzioni checked
e unchecked
vengono usate per verificare il contesto di controllo dell'overflow per le conversioni e le operazioni aritmetiche di tipo integrale. Quando si verifica l'overflow aritmetico di numeri interi, il contesto di controllo dell'overflow definisce cosa accade. In un contesto controllato viene generata una System.OverflowException; se l'overflow si verifica in un'espressione costante, si verifica un errore in fase di compilazione. In un contesto non verificato, il risultato dell'operazione viene troncato rimuovendo tutti i bit di ordine elevato che non rientrano nel tipo di destinazione. Ad esempio, l'addizione esegue il wrapping dal valore massimo al valore minimo. L'esempio seguente mostra la stessa operazione in un contesto verificato e non verificato:
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
Il comportamento di overflow degli operatori e delle conversioni definiti dall'utente può essere diverso da quello descritto nel paragrafo precedente. In particolare, gli operatori verificati definiti dall'utente potrebbero non generare un'eccezione in un contesto controllato.
Per altre informazioni, vedere le sezioni Overflow aritmetico e divisione per zero e Operatori verificati definiti dall'utente dell'articolo Operatori aritmetici.
Per specificare il contesto di controllo dell'overflow per un'espressione, è anche possibile usare gli operatori checked
e unchecked
, come illustrato nell'esempio seguente:
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.
}
Le istruzioni e gli operatori checked
e unchecked
influiscono solo sul contesto di controllo dell'overflow per le operazioni che sono testualmente all'interno delle parentesi del blocco di istruzioni o dell'operatore, come illustrato nell'esempio seguente:
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.
}
Nell'esempio precedente, la prima chiamata della funzione locale Multiply
mostra che l'istruzione checked
non influisce sul contesto di controllo dell'overflow all'interno della funzione Multiply
perché non viene generata alcuna eccezione. Alla seconda chiamata della funzione Multiply
, l'espressione che calcola il secondo argomento della funzione viene valutata in un contesto controllato e restituisce un'eccezione mentre è testualmente all'interno del blocco dell'istruzione checked
.
Il comportamento di checked
e unchecked
dipende dal tipo e dall'operazione. Anche per i numeri interi, le operazioni come unchecked(x / 0)
sempre generano perché non esiste alcun comportamento sensato. Controllare il comportamento per il tipo e l'operazione per comprendere in che modo le checked
parole chiave e unchecked
influiscono sul codice.
Tipi numerici e contesto di controllo dell'overflow
Le checked
parole chiave e unchecked
si applicano principalmente ai tipi integrali in cui è presente un comportamento di overflow sensibile. Il comportamento wraparound in cui T.MaxValue + 1
diventa T.MinValue
sensibile nel valore di complemento di due. Il valore rappresentato non è corretto perché non può rientrare nello spazio di archiviazione per il tipo. Di conseguenza, i bit sono rappresentativi dei n bit inferiori del risultato completo.
Per i tipi come decimal
, double
float
, e Half
che rappresentano un valore più complesso o un valore di complemento, wraparound non è ragionevole. Non può essere usato per calcolare risultati più grandi o più accurati, quindi unchecked
non è utile.
float
, double
e Half
hanno valori di saturazione sensibili per PositiveInfinity
e NegativeInfinity
, in modo da poter rilevare l'overflow in un unchecked
contesto. Per decimal
, non esistono limiti di questo tipo e la saturazione in MaxValue
può causare errori o confusione. Operazioni che usano decimal
generano un'eccezione sia in un contesto che in un checked
unchecked
contesto.
Operazioni interessate dal contesto di controllo dell'overflow
Il contesto di controllo dell'overflow influisce sulle operazioni seguenti:
I seguenti operatori aritmetici predefiniti: operatori unari
++
,--
,-
e binari+
,-
,*
, e operatori/
, quando gli operandi sono di un tipo integrale, ovvero numerico integrale o tipo di char) o un tipo enumerazione.Conversioni numeriche esplicite tra tipi integrali o da
float
odouble
a un tipo integrale.Nota
Quando si converte un valore
decimal
in un tipo integrale e il risultato non rientra nell'intervallo del tipo di destinazione, viene sempre generata un'eccezione OverflowException indipendentemente dal contesto di controllo dell'overflow.A partire da C# 11, gli operatori e le conversioni controllati definiti dall'utente. Per altre informazioni, vedere la sezione Operatori controllati definiti dall'utente dell'articolo Operatori aritmetici.
Contesto di controllo overflow predefinito
Se non si specifica il contesto di controllo dell'overflow, il valore dell'opzione del compilatore CheckForOverflowUnderflow definisce il contesto predefinito per le espressioni non costanti. Per impostazione predefinita, il valore di tale opzione è unset e le operazioni aritmetiche di tipo integrale e le conversioni vengono eseguite in un contesto non verificato.
Le espressioni costanti vengono valutate per impostazione predefinita in un contesto controllato e l'overflow causa un errore in fase di compilazione. È possibile specificare in modo esplicito un contesto non verificato per un'espressione costante con l'istruzione o l'operatore unchecked
.
Specifiche del linguaggio C#
Per altre informazioni, vedere le sezioni seguenti delle specifiche del linguaggio C#:
- Istruzioni Checked e Unchecked
- Operatori Checked e Unchecked
- Operatori controllati e non verificati definiti dall'utente - C# 11
Vedi anche
- Opzione del compilatore CheckForOverflowUnderflow