第13回
エラーメッセージと対処方法(3)~開発手順の効率化

printfデバッグを試す

printfデバッグを試してみましょう。わざと間違えたソースを使い、printf関数でプログラムの動作中に変数の値を表示させてみます。

動作のおかしいプログラム

リスト5は、このコラムで何度か紹介した「九九プログラム」のソースです(バグを調べるという目的なので、計算結果の表示処理をちょっと書き換えてあります)。ただ、うっかりとfor文のところで繰り返し条件を間違えてしまいました(わざとらしいミスですが^^;)。

文法のミスではないので、コンパイルとリンクは正常に終了して実行ファイル(exeファイル)が生成されます。が、実行してみれば間違いは歴然です。入力した値(整数1桁)の段の九九が画面1のように『0~18』の段まで表示されてしまいます。

リスト5:forの条件を書き間違えた「九九プログラム」のソース~(ex1301.c)
#include <stdio.h>

int	main(void)
{
  int i;
  int num;

  printf("Input Base number : ");
  scanf("%d", &num);
  for (i=0; i<19; i++) {
    printf("%d\n", num * i);
  }
  return (0);
}


怪しい箇所で値を表示させる

この程度の間違いならすぐに気付くはずですが、ソースが長く複雑になれば単純なミスさえ目に止まらなくなるでしょう。この場合は「繰り返しの回数が多すぎる→for文が怪しい」と推測できます。そこで、リスト6のように★マークの箇所に
printf("DEBUG : i = %d\n", i);
という1文を挿入します。for文のカウンタ変数 i の値を表示する処理です。

すると、画面2のように、forループを1回実行するごとに計算結果の前に変数 i の値が表示されます。これを見れば、どこをどう間違えたのかはすぐに分かります。間違った箇所を修正したのがリスト7、その実行結果が画面3です。

printfデバッグはシンプルですが、なかなか役に立ちます。重要なことは、プログラムを実行しておかしな結果が現れたときに、ソースのどの部分を調べればよいかを推測することです。これは、デバッガを使った本格的なデバッグでも同じです。

なお、デバッガを使ったデバッグやもっと複雑なソースで論理的なエラーを発見し対処するためのノウハウについては、回を追って取り上げる予定です。

リスト6:カウンタ変数 i の値を調べるためにprintf文を挿入した~(ex1302.c)
#include <stdio.h>

int	main(void)
{
  int i;
  int num;

  printf("Input Base number : ");
  scanf("%d", &num);
  for (i=0; i<19; i++) {
    printf("DEBUG : i = %d\n", i); -------------- ★
    printf("%d\n", num * i);
  }
  return (0);
}


リスト7:間違いを修正した「九九プログラム」(ex1303.c)
#include <stdio.h>

int	main(void)
{
  int i;
  int num;

  printf("Input Base number : ");
  scanf("%d", &num);
  for (i=1; i<=9; i++) {
    printf("%d\n", num * i);
  }
  return (0);
}


あとがき

hiropの『ちょっと気になる専門用語』~《バグ》

ご存じのように、バグ(bug)とは蛾のような羽虫を意味します。英語では昆虫をinsect、ミミズのようにうじゃうじゃといる虫をworm……などと種類分けされています(と言っても、実際にはさほど厳密に使い分けられているものでもないようです)。

対して、日本語の「虫」は非常に広範囲な意味を持っており、古い日本語ではヘビ(蛇)も虫の仲間とされていました(漢字には虫偏が付いています)。かなり大きなサイズまで許容されていたようです。

バグと言えば、事務用プログラミング言語の雄・COBOLの生みの親グレース・マレー・ホッパー女史のエピソードが有名です。ハーバード大学で開発されたコンピュータ“Harvard Mark II”のリレー(継電器)に蛾(本物のバグ)が入り込んで故障したことがあり、それ以降、ホッパー女子は進捗状況を訪ねられるたびに「バグを取ってます」と答えた──と、いうものです。

これが業界に定着して、プログラムの不具合を「バグ」と呼ぶようになったという説もあります。が、まだコンピュータの生まれていない19世紀、既に機械の不調の原因に対して“bug”という言葉が使われていました。実際bugには、口語で「機械や計画の欠陥、誤り」「盗聴器」などの意味があります。

いずれにせよ、よい意味で使われる語ではありません。日本語でも「虫」にはあまりよい意味がないため『bug→悪さをする虫、debug→虫退治』という表現がすんなりと受け入れられたのでしょう。

なお、英語の“bug”にも日本語の『虫』にも「何かに夢中になっている人」という同じ意味があります。本の好きな人を日本語で「本の虫」と言いますが、英語でも“a book bug”と言います。

ただ、今では「bug=間違い」という意味の方が広まってbook bugは「正誤表」(list of errata)を指すことが多いようです。

確かに日本でも「彼は本の虫だ」といった表現は、あまり使われなくなりました。「バグ」という言葉も一般化して「あいつバグってるよ」などと使われたりします。コンピュータが広まり、図書館ではなくネットで調べ物をするこの時代。本を読む人が少なくなったからかもしれません。