CA2233: 操作はオーバーフローできません
TypeName |
OperationsShouldNotOverflow |
CheckId |
CA2233 |
分類 |
Microsoft.Usage |
互換性に影響する変更点 |
なし |
原因
メソッドで算術演算が実行され、オーバーフローが発生する前にオペランドの検証が完了しません。
規則の説明
まずオペランドを検証し、演算結果が関連するデータ型で使用できる値の範囲を超えないことを確認してから、算術演算を実行します。実行コンテキストおよび関連するデータ型によって変わりますが、算術オーバーフローによって OverflowException または結果の最上位ビットが破棄されます。
違反の修正方法
この規則違反を修正するには、演算を実行する前にオペランドを検証します。
警告を抑制する状況
オペランドで使用できる値によって算術演算のオーバーフローが発生しない場合、この規則による警告を抑制しても安全です。
違反の例
説明
次の例にあるメソッドは、この規則に違反する整数を操作します。Visual Basic では、これを実行するには Remove 整数のオーバーフロー オプションを無効にする必要があります。
コード
Imports System
Public Module Calculator
Public Function Decrement(ByVal input As Integer) As Integer
' Violates this rule
input = input - 1
Return input
End Function
End Module
using System;
namespace Samples
{
public static class Calculator
{
public static int Decrement(int input)
{
// Violates this rule
input--;
return input;
}
}
}
コメント
この例のメソッドに MinValue が渡される場合、演算はアンダーフローします。これにより、結果の最上位ビットは破棄されます。このしくみを次のコードに示します。
[C#]
public static void Main()
{
int value = int.MinValue; // int.MinValue is -2147483648
value = Calculator.Decrement(value);
Console.WriteLine(value);
}
[VB]
Public Shared Sub Main()
Dim value = Integer.MinValue ' Integer.MinValue is -2147483648
value = Calculator.Decrement(value)
Console.WriteLine(value)
End Sub
出力
2147483647
入力パラメーターの検証による修正
説明
入力の値を検証することによって上記の違反を修正するコード例を次に示します。
コード
Public Module Calculator
Public Function Decrement(ByVal input As Integer) As Integer
If (input = Integer.MinValue) Then _
Throw New ArgumentOutOfRangeException("input", "input must be greater than Int32.MinValue")
input = input - 1
Return input
End Function
End Module
using System;
namespace Samples
{
public static class Calculator
{
public static int Decrement(int input)
{
if (input == int.MinValue)
throw new ArgumentOutOfRangeException("input", "input must be greater than Int32.MinValue");
input--;
return input;
}
}
}
checked ブロックによる修正
説明
checked ブロックで演算をラップすることによって上記の違反を修正するコード例を次に示します。演算がオーバーフローする場合は、OverflowException がスローされます。
checked ブロックは、Visual Basic ではサポートされていません。
コード
using System;
namespace Samples
{
public static class Calculator
{
public static int Decrement(int input)
{
checked
{
input--;
}
return input;
}
}
}
演算のオーバーフローおよびアンダーフローのチェックの有効化
C# で演算のオーバーフローおよびアンダーフローのチェックを有効にすると、すべての整数演算を checked ブロックでラップしたときと同じ結果が得られます。
C# で演算のオーバーフローおよびアンダーフローのチェックを有効にするには
ソリューション エクスプローラーで、プロジェクトを右クリックし、[プロパティ] をクリックします。
[ビルド] タブをクリックし、[詳細設定] をクリックします。
[演算のオーバーフローおよびアンダーフローのチェック] を選択し、[OK] をクリックします。