Cygwinでデバッグ

不可解な動作

コンパイルエラーも出ないし、実行させてもエラーは出ないけれども、思った通りの動きをしない場合に、どこから調べればよいのか、ヒントを書いてみます。

警告レベルを上げる

gcc コンパイラには、オプションによって動作を切り替える指示を出すことができます。以下のように、

gcc -Wall hoge.c

と "-Wall"(Warning all の意味)のオプションを付けると、警告してくれる項目が増えます。例えば次のような時に警告してくれます。

この "-Wall" オプションは、完成する a.exe には影響しないので、常につけておくことをお勧めします。~/.bash_profile に以下のように書き込んでおけば、常にこのオプションがついていることになります。

alias gcc='gcc -Wall'

Windows 上のファイラーでは、このような名前のファイルを作ることは難しいので、Cygwin 上での操作方法を書いておきます。次のコマンドを実行するとよいでしょう。

echo "alias gcc='gcc -Wall'" >> ~/.bash_profile

変数の値を表示させる

printf("a = %d\n", a);
fprintf(stderr, "a = %d\n", a);

余分なセミコロン

if/while/for の後ろに ";" が付いていると、ほぼバグです。

if ( x == 0 );  ←この ";" が余分
{
    printf("x is zero.\n");
}

行末のセミコロンは違和感がないため、if/while/for の後ろについていても見逃してしまいがちです。

「ブロックの中身が空っぽ」というのは、確かに if では不自然ですが、for や while では多用される例もありますので、ブロックが空というだけでコンパイラが警告してくれることは期待できないでしょう。

このバグを未然に防ぐためには、ブロックの書き方を変更してみるのもよいかもしれません。例えば以下のようなスタイルであれば、このバグは起こり得ません。

if ( x == 0 ) {
    printf("x is zero.\n");
}

この {} のスタイルを好む人は、行数を少なくできることに意義を見出していることが多いので、バグの防止に関しては副作用と言えるかもしれません。しかしながら(痛い目にあった人にとっては)効果は大きいので、検討してみる価値は十分にあるでしょう。

なお、ブロック {} のスタイルについては、C 言語の教科書たる K&R では、首尾一貫していることを重要視していて、どれがよいというような評価はしていません。

また、世間のプロジェクトの多くではコーディングスタイルが決められていて、その中にブロックの書き方も規定されていて、個人の趣味が通用しないことも大いにありえます。

さらに、エディタや開発環境によっては自動フォーマットの機能を持つものがあって、それで整形してしまえばどのスタイルを選んでいても関係なくなってしまいます。


トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS