- 追加された行はこの色です。
- 削除された行はこの色です。
#author("2020-11-10T11:36:05+09:00","default:tutimura","tutimura")
#author("2020-11-15T16:21:14+09:00","default:tutimura","tutimura")
[[Cygwinでデバッグ]]
#contents
** エラーの出ない場合 [#jdcd6295]
*** デバッグライト [#za88de3a]
プログラムの動作の詳細を確かめるために、変数の値を表示させるのは、どの言語にも通用する、一番基本的な手法です。この変数表示のプリント文のことを「デバッグライト」(debug write) といいます。
プログラムの動作の詳細を確かめるために、変数の値を表示させるのは、どの言語にも通用する、プリントデバッグと呼ばれる、もっとも基本的な手法です。この変数表示のプリント文のことを「デバッグライト」(debug write) といいます。
デバッグライトには、いくつかコツがあります。
- 変数の値の変化する後や、条件の成り立った直後、関数に入った直後などに表示させます。
- 表示形式は "関数名: 変数名=値, 変数名=値" のような形式が好まれます。
- 表示形式は "関数名: 変数名=値, 変数名=値" のような形式が好まれます。(関数名の部分は、C99からは __func__ という特殊な変数を用いると便利です。)
- 最終的には不要になるコードですが、削除してしまわずに、コメントにして残しておきます。そうすることで、次に改造するときの役にも立ちますし、プログラムのこの部分が間違いやすいという目印にもなります。
/* 1からn の合計を求める */
int sum(int n) {
int ret = 1; // 初期値がおかしいのだが...
for (int i=1; i<=n; i++) {
ret = ret + i;
printf("sum: i=%d, ret=%d\n", i, ret); // デバッグライト
printf("%s: i=%d, ret=%d\n", __func__, i, ret); // デバッグライト
}
return ret;
}
このようなプログラムを実行すると、
sum: i=1, ret=2
sum: i=2, ret=4
...
と表示されて、ret の初期値のおかしいことに気付けるでしょう。
メモリの不正アクセスなどでプログラムが中断される場合には、printしたはずの文字が表示されないことがよくあります。C言語のライブラリでは、処理の効率化のために、表示する内容は一旦バッファに蓄えてから、あるタイミングで表示することが多いです。不正終了した場合は、バッファにたまったまま表示されませんので、対策が必要です。いくつか方法があります。
メモリの不正アクセスなどでプログラムが中断される場合には、プリントしたはずの文字が表示されないことがよくあります。C言語のライブラリでは、処理の効率化のために、表示する内容は一旦バッファに蓄えてから、あるタイミングでまとめて表示する、といったことがなされています。不正終了した場合は、バッファにたまったまま表示されませんので、対策が必要です。いくつか方法があります。
- fflush(stdout); で強制的に表示させます。(「フラッシュする」と言います。)
- fprintf(stderr, "sum: i=%d, ret=%d\n", i, ret); と標準エラー出力を用いるとバッファリングされないことが多いです。
- printf("...\n"); と改行を含めると、このタイミングでフラッシュされることが多いです。
しかしながら、メモリを破壊しているような場合には、直後に停止するわけでもなく、printf()1つ追加するだけで動作が変わることもありますので、「これが表示されたから、ここまでは正しく動作している」というのがあてにならないこともママあります。