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# で演算のオーバーフローおよびアンダーフローのチェックを有効にするには

  1. ソリューション エクスプローラーで、プロジェクトを右クリックし、[プロパティ] をクリックします。

  2. [ビルド] タブをクリックし、[詳細設定] をクリックします。

  3. [演算のオーバーフローおよびアンダーフローのチェック] を選択し、[OK] をクリックします。

参照

関連項目

C# 演算子

Checked と Unchecked (C# リファレンス)

OverflowException