バグ検出ドリル(8)電卓プログラムのような小さなプログラムにもバグがいる:山浦恒央の“くみこみ”な話(108)(4/4 ページ)
学生プログラミングの課題となるような小さいプログラムでもバグが潜んでいます。「バグ検出ドリル」の第8回では、学生が5分で書けるような電卓プログラムに潜むバグを見つけ出してください!
5.解答
今回の解答を下記に示します。
(1)オーバーフロー
計算結果が、int型の範囲を超える場合、オーバーフローとなります。筆者の環境は、Visual Studio 2010コンソールアプリケーションで作成しており、int型のとり得る範囲は、下記となります。
最小値 | 最大値 | |
---|---|---|
int型 | -2147483648 | 2147483647 |
「電卓プログラム」の加算と乗算を実行し、上記の最大値や最小値を超えると、オーバーフローします※1)。
オーバーフローのバグは、常習的なバグとして昔から有名で、これを防ぐには、最大値が入力されても溢れない十分な大きさの変数を確保するとか、入力しないよう使い方に制限をかける必要があります※2)。
※1)この1行を読んで、「オーバーフローは加算と乗算だけじゃないだろ」と思った方は正解です。オーバーフローは、加算、乗算だけでなく、減算、除算でも発生します。-2147483648(最小値)を「-1」で除算すると、2147483648となり、最大値を越えます。また、-2147483648(最小値)から「1」を減じても、オーバーフローします。
※2)今回の問題では、scanfを使っています。この標準関数は、大半の学生プログラムで慣習的に使いますが、異常処理を回避するのが非常に難しい関数として有名です。ある意味、くせ者関数ですね。例えば、本問題で文字などの異常値を入力すると、ハングアップします。大学の教員の中には、「scanfを学生に教えるな」と言う人もいます。
(2)ゼロ除算
2つ目の入力値に0をセットするとゼロ除算が発生し、本プログラムはフリーズします。ゼロ除算は、0による除算を実施することで発生するバグです。これも古典的で常習的な「あるあるバグ」で、今まで多くのソフトウェアで甚大な被害を与えてきました。この問題を解決するには、0の時は、計算しないなどの工夫が必要です。例えば、Windowsの標準ツールの「電卓」アプリで、「4 / 0」を入力すると、「0で割ることが出来ません」と表示が出ます。
「電卓プログラム」の場合は、ゼロ除算で大きな影響が出ることはありませんが、ミッション・クリティカルなプログラムでは、重大事故に直結します。ソフトウェアの中に割り算処理があれば、ゼロ除算が起きないガードがあるか、十分注意しましょう。
6.自己採点シート
問題 | 内容 | 配点(点) |
---|---|---|
電卓プログラムの問題 | 5分以上考えた | 50 |
加算、乗算でオーバーフローの可能性を見つけた | 15 | |
減算、除算でオーバーフローの可能性を見つけた | 10 | |
ゼロ除算の可能性を見つけた | 25 | |
上記以外のバグを見つけた | +α | |
リスト6 自己採点シート |
7.終わりに
短いプログラムでも、バグなしで作るのは簡単ではありません。今回は、学生が数分で書ける電卓プログラムを出題しました。小さいプログラムでも、異常処理を考えると、いろいろなことを考慮せねばなりません。
オーバーフローやゼロ除算は、昔から有名な常習的バグです。仕様の段階からしっかりとレビューして見つけるか、テスト工程で同値分割を適用し、確実に摘出できるようにしましょう。
今までの問題もそうですが、筆者が想定していないバグや考え違いもあるでしょう。それも合わせて見つけていただければと思います。
東海大学 大学院 組込み技術研究科 非常勤講師(工学博士)
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- ≫連載「山浦恒央の“くみこみ”な話」バックナンバー
- バグ検出ドリル(7)やっぱり、いろんなところにバグがいる!
重要顧客の前でデモを行う際にバグが発生すると大変です。顧客だけでなく、自社の社長まで同席していたいたときなどは、さらにものすごく焦るのではないでしょうか。「バグ検出ドリル」の第7回では、そんな状況を想定しつつ、いろんなところに潜むバグを見つけ出してください! - バグ検出ドリル(6)いろんなところにバグがいる! 2分探索法の問題
「バグ検出ドリル」の第6回で出題するのは「2分探索法」の問題です。ソフトウェア技術者の誰もが心得ておくべき常識的なアルゴリズムである2分探索法ですが、今回の問題では、いろんなところにバグがあります。問題文から、どこにバグがありそうか見つけ出してみよう! - バグ検出ドリル(5)「小さな親切、大きなお世話」な問題
「バグ検出ドリル」の第5回で出題するのは「思い込み」にまつわるバグの問題です。タイトルの「小さな親切、大きなお世話」とは一体何なのでしょうか。問題文から、どこにバグがありそうか見つけ出してみよう! - バグ検出ドリル(4)プログラミングの素質を試すのに最適!? FizzBuzz問題に挑戦
「バグ検出ドリル」の第4回で出題するのは、プログラミングの素質を試すのに最適といわれる伝説の「FizzBuzz問題」。問題文から、どこにバグがありそうか見つけ出してみよう! - バグ検出ドリル(3)それでもプログラマーは数学を知っておくべきだ
「バグ検出ドリル」の第3回で出題するのは、前回に引き続き数学に関係する問題。理系とはいえ必ずしも数学が得意ではないプログラマーですが、やはり数学を知るメリットは絶大。これまでと比べてかなり歯ごたえ十分な問題を用意したので、じっくり取り組んで数学に対する免疫力をつけてみよう!