ソフトウェア技術者のためのバグ百科事典(17)無限ループやbreak抜け、コーディングのバグ再び:山浦恒央の“くみこみ”な話(138)(2/3 ページ)
ソフトウェア技術者に向けて、バグに関する基礎知識をまとめていく新シリーズ「バグ百科事典」。第17回は、第14回でテーマにしたコーディングのバグを再び取り上げます。無限ループやbreak抜けなどまだまだあります!
4.筆者がやってしまったバグ
開発リソースの関係上、同僚の作成途中のプログラムを引き継ぎました。プログラムには問題があるらしく、既知の事象として、終了処理が正しく動きません。同僚の人は筆者よりも経験があるエンジニアで、きっと見つけにくいバグに違いないと思いました(リスト5)。
#include <stdio.h> #include <stdlib.h> typedef enum { MODE_POWER_OFF, //電源OFFモード MODE_POWER_ON //電源ONモード }MODE; typedef enum { EVENT_POWER_OFF, //電源OFF指令 EVENT_POWER_ON //電源ON指令 }EVENT; int main() { int mode = MODE_POWER_ON; //初期状態は電源ONモード int input; while (1) { if (mode == MODE_POWER_OFF) { printf("現在のモード:電源OFF\n"); } else { printf("現在のモード:電源ON\n"); } printf("0:電源OFFイベント 1:電源ONイベント\n"); scanf("%d", &input); switch (mode) { case MODE_POWER_OFF: printf("ここの行には到達できない\n"); exit(1); //プログラム終了 case MODE_POWER_ON: if (input == EVENT_POWER_OFF) { printf("「mode = MODE_POWER_OFF」と書くはずだった\n"); mode == MODE_POWER_OFF; } break; } } return 0; }
リスト5には、筆者が見つけたバグの例(イメージ)を示しました。イメージなので、おかしいところは無視してください。
このプログラムでは、「電源ONモード」「電源OFFモード」の2つの状態と、「電源OFF指令」「電源ON指令」の2つのイベントを持っています。
typedef enum { MODE_POWER_OFF, //電源OFFモード MODE_POWER_ON //電源ONモード }MODE; typedef enum { EVENT_POWER_OFF, //電源OFF指令 EVENT_POWER_ON //電源ON指令 }EVENT;
プログラムは、無限ループで動いており、コンソール入力が0(電源OFFイベント)の場合、プログラム終了することになっています。なお、コンソール入力で「1」を入力したときの電源ONイベントの処理は、説明の都合上、省略しました。
プログラムの開始では、「int mode = MODE_POWER_ON;」で電源ONモードから開始し、電源OFF指令(コンソールから「0」を入力)で、プログラムを終了したいと考えています。
以下の通り、プログラムを終了するため、電源OFF指令(コンソール入力では0)を送り、電源OFFモード(MODE_POWER_OFF)に遷移しようとしています。
case MODE_POWER_ON: if (input == EVENT_POWER_OFF) { printf("「mode = MODE_POWER_OFF」と書くはずだった\n"); mode == MODE_POWER_OFF; } break; }
一見よさそうに見えますが、問題は、「mode = MODE_POWER_OFF;」とするべきところが、「mode == MODE_POWER_OFF;」となっており、変数modeの値が、変更できていません。結果として、電源OFFモードに遷移できず、ずっと電源ONモードのままとなりました。
当初、筆者は、「何らかの複雑なメモリ破壊を起こしているのだろう」と疑っていましたが、ただの代入の記述ミスと判明し、拍子抜けしました。
Copyright © ITmedia, Inc. All Rights Reserved.