より良いエンジニアを目指して

1日1つ。良くなる!上手くなる!

int.MaxValue * 2 は? a *= 2; というコードでアプリが落ちるお話

会社でシステムテストをしていたところ、チームのメンバーで

項目Aに入力出来る最大の数値を入れて、(私が開発した)機能Bを使うと落ちる

という報告がありました。

嘘ー、そんなことあるの!?と。

私、前職では参照用のアプリケーションだったので、このあたりの入力値の最大値、限界値の恐ろしさを知りませんでした。

どうやら私の機能Bで入力された値に対して、乗算しているところが原因だった模様。

a *= 2

至って普通のコードです。

しかし、このaがint.MaxValueだったら、どうなるでしょうか?

using System;
                    
public class Program
{
    public static void Main()
    {
        int a = int.MaxValue;
        a *= 2;
        Console.WriteLine(a);
    }
}

f:id:rimever:20200711143953p:plain
-2になります

正の値にしかならないような値がマイナスになってしまい、正の値と思って処理したらエラーとなってしまったのです。

そしてアプリが落ちると。

間違った値のまま処理してしまっても、それはそれでおかしな値があちこちに伝播して危ないですし、とはいえ、デスクトップアプリケーションでアプリが落ちるというのはダメなので対応が迫られます。

対応としては、以下の二つを考えました。

  • if ( a <= int.MaxValue / 2) で有効な演算のみを算出する。
  • a *= 2の後に、マイナスになっていたら、a = int.MaxValueを再代入して補正する

そもそもaが限界超えることが異常であるので、正常系のコードが明解になることを優先し、既存コードでも使われているという観点からマイナスになったときに補正しておくことに止める方を判断しました。