2008年2月6日水曜日

初期化の大切さ改めて実感

初期化していないがためのバグ
コンパイル時の最適化と合わさって
検出にえらい時間がかかってしまった…

問題になったコードの要点だけ抜き出してみた。
C++/CLIでは変数宣言すると勝手に初期化してくれるという
前提やのに。。。動いてなかってん。
------------------------
int i = 0;
for(i = 0; i < 20; ++i) {
int b; // ゼロで自動的に初期化されてるねん♪
b++;
printf("%d\n", b);// 必ず1が出力されることを期待
}
------------------------

ループの中で変数を宣言すると、毎回メモリ確保やん。
効率悪いってのでコンパイラが自動的にループの外で宣言してくれるねん。

↓コンパイル後はこのような意味のコードになってる
------------------------
int i = 0;
int b; // ゼロで自動的に初期化されてるねん♪
for(i = 0; i < 20; ++i) {
b++;
printf("%d\n", b);// 必ず1が出力されることを期待
}
------------------------
そりゃ期待する結果が得られるわけ無いやん…。


変数宣言時に初期化するように修正したコード
------------------------
int i = 0;
for(i = 0; i < 20; ++i) {
int b = 0; // 明示的にゼロで初期化してやった!
b++;
printf("%d\n", b);// 必ず1が出力されることを期待
}
------------------------

コンパイルするとこのような意味のコードになってる
------------------------
int i = 0;
int b; // ゼロで自動的に初期化されてるねん♪
for(i = 0; i < 20; ++i) {
b = 0; // ここが違う!
b++;
printf("%d\n", b);// 必ず1が出力されることを期待
}
------------------------
これで修正完了っと。
他にもコンパイル時の最適化はいろいろあるので覚えておいて損は無いかも。
WikiPedia「コンパイラ最適化」


教訓:
初期化し忘れで出たバグは非常に見つけ難い…(^^;
変数宣言時は初期化する癖をつけよう!

.

0 件のコメント:

ラベル