ブログ「サイバー少年」

ブログ「サイバー少年」へようこそ!
小学六年生ごろからプログラミングを趣味にしている高校生のブログです。
勉強したことについての記事などを書いています。フリーソフトも制作、公開しています。
(当ブログについて詳しくは「ブログ概要紹介」を参照)

サイバー少年が作ったフリーソフトは「サイバー少年の作品展示場」へ

[C#] 整数演算のオーバーフローが無視される。

今日は、C#やVB.NETを扱う時、注意すべき点に気づいたのでご紹介します。

C#でこんなコードを書いてみましょう。

byte b = byte.MaxValue;
b++;
Console.Write(b);

C#が出来る人は、このコードのおかしい部分に気づくと思います。
これだと、255+1でオーバーフローしてしまうのです。

コンパイルエラーは無く、ビルドに成功しました。
しかし、これだと実行時にオーバーフローで、
エラーが起きるはずです。

しかし、実行時エラーは起きませんでした。
かなりおかしい事でしょう。
では一体、bの値はどうなっているのでしょうか。

出力結果
0

bの値は0になっていました。
エラーを返さず、この結果です。

さて、お分かりかと思いますが、なぜこうなるかは単純です。
byte型は8ビット符号なしの値を扱うため、
11111111 + 1 = 100000000で、結果が00000000になるのです。

このbyteをuintに変えて、

uint i = uint.MaxValue;
i++;
Console.Write(i);

と書いても、結果は0が出力されます。

intなどの符号ありの型を使うと

int i = int.MaxValue;
i++;
Console.Write(i);

出力結果
-2147483648

結果はマイナスになります。
これも、正の最大値に1足すと、負の最小値になる事は当然ですね。


つまり、C#でも
オーバーフローによる例外は発生せず、コンピュータ的にそのままの結果が返ってくるのです。

これを知った時、私は少しショックでした…。

C#はハードウェアの世界から分離された超高級言語のはずなのに、
この結果はそのまま返って来るではありませんか。

しかし、そこはC#です。
この時、例外を返すように設定できるのです。

プロジェクト設定のビルドタブ
→ビルドの詳細設定
→「演算のオーバーフローおよびアンダーフローのチェック」
とある項目にチェックすると設定完了です。

この状態で上記のコードを実行すると、実行時エラーが返ってきます。


この設定、デフォルトではOFFなんですよね…。
私的には、デフォルトでONにして欲しいです。

C#にはハードウェアの抽象化を期待しているので。

tag:

コメント

コメントの投稿

トラックバック

トラックバック URL
http://cyberboy6.blog.fc2.com/tb.php/179-0549d159
この記事にトラックバックする(FC2ブログユーザー)

当ブログをご利用(閲覧等)になる場合は必ず「当ブログの利用規定」をお守りください。