検索
連載

ソフトウェア技術者のためのバグ百科事典(17)無限ループやbreak抜け、コーディングのバグ再び山浦恒央の“くみこみ”な話(138)(2/3 ページ)

ソフトウェア技術者に向けて、バグに関する基礎知識をまとめていく新シリーズ「バグ百科事典」。第17回は、第14回でテーマにしたコーディングのバグを再び取り上げます。無限ループやbreak抜けなどまだまだあります!

Share
Tweet
LINE
Hatena
※本記事はアフィリエイトプログラムによる収益を得ています

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 状態遷移関連のプログラムの例(イメージ)

 リスト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;
リスト5の抜粋(再掲)

 プログラムは、無限ループで動いており、コンソール入力が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;
}
リスト5の抜粋(再掲)

 一見よさそうに見えますが、問題は、「mode = MODE_POWER_OFF;」とするべきところが、「mode == MODE_POWER_OFF;」となっており、変数modeの値が、変更できていません。結果として、電源OFFモードに遷移できず、ずっと電源ONモードのままとなりました。

 当初、筆者は、「何らかの複雑なメモリ破壊を起こしているのだろう」と疑っていましたが、ただの代入の記述ミスと判明し、拍子抜けしました。

Copyright © ITmedia, Inc. All Rights Reserved.

ページトップに戻る