checked ステートメントと unchecked ステートメント (C# リファレンス)
checked
および unchecked
ステートメントを使って、整数型の算術演算および変換に対するオーバーフローチェック コンテキストを指定します。 整数の算術オーバーフローが発生した場合、オーバーフローチェック コンテキストによって動作を定義します。 checked コンテキストでは、System.OverflowException がスローされます。定数式でオーバーフローが発生すると、コンパイル時のエラーが発生します。 unchecked コンテキストでは、結果の格納先の型に収まらない上位ビットが破棄されて、演算結果が切り詰められます。 たとえば、加算は最大値から最小値まで折り返されます。 次の例は、checked と unchecked の両方のコンテキストで行った同じ演算を示しています。
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.
}
Note
ユーザー定義演算子と変換のオーバーフロー動作は、前の段落で説明した動作とは異なる場合があります。 特に、ユーザー定義の checked 演算子は、checked コンテキストで例外をスローしない可能性があります。
詳細については、算術演算子に関する記事の「算術オーバーフローと 0 による除算」と「ユーザー定義の checked 演算子」のセクションを参照してください。
式のオーバーフロー チェック コンテキストを指定するには、次の例に示すように、checked
と unchecked
の演算子を使用することもできます。
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.
}
checked
と unchecked
のステートメントと演算子は、次の例に示すように、ステートメント ブロックまたは演算子のかっこ内で "テキストとして表示される" 演算子のオーバーフロー チェック コンテキストにのみ影響します。
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.
}
前の例の Multiply
ローカル関数の最初の呼び出しは、例外がスローされないため、checked
ステートメントが Multiply
関数内のオーバーフロー チェック コンテキストに影響しないことを示しています。 Multiply
関数の 2 番目の呼び出しでは、関数の 2 番目の引数を計算する式が checked コンテキストで評価され、その結果、例外となります。これは、checked
ステートメントのブロック内にテキストとして表示されているためです。
checked
とunchecked
の動作は、種類と操作によって異なります。 整数の場合でも、 unchecked(x / 0)
のような操作は、賢明な動作がないため、常にスローされます。 型と操作の動作を確認して、 checked
キーワードと unchecked
キーワードがコードに与える影響を理解します。
数値型とオーバーフロー チェック コンテキスト
checked
キーワードとunchecked
キーワードは、主に、適切なオーバーフロー動作がある整数型に適用されます。 T.MaxValue + 1
がT.MinValue
になるラップアラウンド動作は、2 つの補数値で適切です。 表される値は 修正されません 型のストレージに収まらないためです。 したがって、ビットは、結果全体の下位 n ビットを代表します。
より複雑な値または補数値を表す decimal
、 float
、 double
、 Half
などの型の場合、ラップアラウンドは賢明ではありません。 より大きい、またはより正確な結果を計算するために使用できないため、 unchecked
は有益ではありません。
float
、 double
、および Half
には、 PositiveInfinity
と NegativeInfinity
の適切な飽和値があるため、 unchecked
コンテキストでオーバーフローを検出できます。 decimal
の場合、このような制限は存在せず、MaxValue
で飽和するとエラーや混乱につながる可能性があります。 decimal
使用する操作は、checked
とunchecked
の両方のコンテキストでスローされます。
オーバーフロー チェック コンテキストの影響を受ける演算
オーバーフロー チェック コンテキストは、次の演算に影響します。
次の組み込みの算術演算: オペランドが整数型である (つまり、整数数値または char 型である) か、enum 型である場合、単項
++
、--
、-
、および二項+
、-
、*
、および/
演算。整数型間か、
float
またはdouble
から整数型への明示的な数値変換。注意
decimal
値を整数型に変換し、結果が格納先の型の範囲外にある場合、OverflowException はオーバーフロー チェック コンテキストに関係なく、常にスローされます。C# 11 以降では、ユーザー定義の checked 演算子と変換。 詳細については、算術演算子に関する記事の「ユーザー定義のチェック演算子」セクションを参照してください。
既定のオーバーフロー チェック コンテキスト
オーバーフロー チェック コンテキストを指定しない場合、 CheckForOverflowUnderflow コンパイラ オプションの値によって、非コンスタント式の既定のコンテキストが定義されます。 既定では、そのオプションの値が設定解除され、整数型の算術演算と変換が unchecked コンテキストで実行されます。
定数式は、チェックされたコンテキストで既定で評価され、オーバーフローによってコンパイル時エラーが発生します。 unchecked
ステートメントまたは演算子を使用して、定数式の unchecked コンテキストを明示的に指定できます。
C# 言語仕様
詳細については、「C# 言語仕様」の次のセクションを参照してください。
関連項目
.NET