C ++コアガイドラインには、ES.20:常にオブジェクトを初期化するというルールがあります。
使用前設定エラーとそれに関連する未定義の動作を避けます。複雑な初期化の理解に関する問題を回避します。リファクタリングを簡素化します。
しかし、このルールはバグを見つけるのに役立ちません。バグを隠すだけです。
プログラムに初期化されていない変数を使用する実行パスがあると仮定します。これはバグです。未定義の動作はさておき、それはまた何かがうまくいかなかったことを意味し、プログラムはおそらくその製品要件を満たしていません。本番環境に展開されると、金銭的な損失が発生する可能性があります。
バグをどのように選別しますか?テストを作成します。しかし、テストは実行パスの100%をカバーするわけではなく、テストはプログラム入力の100%をカバーすることはありません。それ以上に、テストでさえ欠陥のある実行パスをカバーします-それはまだパスできます。結局、これは未定義の動作であり、初期化されていない変数はある程度有効な値を持つことができます。
ただし、テストに加えて、0xCDCDCDCDのようなものを初期化されていない変数に書き込むことができるコンパイラーがあります。これにより、テストの検出率がわずかに向上します。
さらに良いことには、初期化されていないメモリバイトのすべての読み取りをキャッチするAddress Sanitizerなどのツールがあります。
最後に、静的アナライザーがあります。これは、プログラムを調べて、その実行パスに事前設定読み取りがあることを伝えることができます。
そのため、多くの強力なツールがありますが、変数を初期化すると、サニタイザーは何も見つかりません。
int bytes_read = 0;
my_read(buffer, &bytes_read); // err_t my_read(buffer_t, int*);
// bytes_read is not changed on read error.
// It's a bug of "my_read", but detection is suppressed by initialization.
buffer.shrink(bytes_read); // Uninitialized bytes_read could be detected here.
// Another bug: use empty buffer after read error.
use(buffer);
別のルールがあります-プログラムの実行でバグが発生した場合、プログラムはできるだけ早く停止する必要があります。そのままにしておく必要はありません。ただクラッシュし、クラッシュダンプを作成して、調査のためにエンジニアに渡してください。
変数を不必要に初期化すると、逆のことが行われます。そうでない場合、プログラムはすでにセグメンテーションフォールトを取得しているはずですが、プログラムは存続しています。
\0
はバグがあります。それに対処しないように文書化されている場合、呼び出し元のコードにはバグがあります。あなたがチェックするためにあなたを呼び出すコードを修正した場合bytes_read==0
、あなたが開始したところに、使用を呼び出す前に、あなたがしているバック:あなたのコードはバグがある場合は、あなたが初期化しないbytes_read
、あなたがしなければ、安全な。(通常、エラーの場合でも関数は出力パラメーターを埋めることになっています。実際にはそうではありません。出力が放置されるか、未定義になることがよくあります。)
err_t
返すものを無視する理由はありmy_read()
ますか?例のどこかにバグがある場合、それだけです。
bytes_read
変更されていない(ゼロが保持されている)場合、なぜこれがバグであると考えられますか?プログラムは、bytes_read!=0
その後暗黙的に予期しない限り、正常な方法で続行できます。だから、良い消毒剤は文句を言わない。一方、bytes_read
事前に初期化されず、プログラムは正気の方法で継続することができなくなりますので、初期化しないbytes_read
、実際に導入し、事前に存在しなかったバグを。