8

これがばかげた質問ならごめんなさい:-)

バックグラウンド

私は次のようなレガシーコードを持っています:

struct {
int field1;
int field2;
int field3;
int field4;
... many many fields
} myStruct;


while (something) {
initialzationFunction(&myStruct);

// ...change fields of myStruct and do stuff.
}

whileループを繰り返すたびに、myStructが何かに初期化される必要があります。たとえばゼロとしましょう。initialzationFunctionは、myStructのすべてのフィールドをゼロに初期化します。

質問

initialzationFunctionをwhileループ内に保持するのは良いですか、それともループの前に1回呼び出して、プログラマーがこのコードを変更した場合に必要なものを「手動で」初期化するのがよいでしょう。

編集:残念ながら、myStructはグローバル変数であるため、自動変数にすることは、それを使用する多数のレガシー関数にパラメーターとして渡したい場合を除いて、オプションではありません。

私が思うこと

  • initialzationFunction()を呼び出すだけで、誰かがコードを変更し、後でmyStructを初期化するのを忘れた場合のバグを防ぐことができます。
  • どの特定のフィールドが初期化されているかを確認する方が有益な場合があります。
  • whileループの後半で変更されるフィールドが少ない場合は、すべてのフィールドを初期化するinitialzationFunction()の呼び出しは冗長です。

あなたならどうしますか?

4

5 に答える 5

6

他の人が維持できるようにコードを残していて、コードが実証済みのホットスポットではない場合は、他の人によって導入されるバグが少なくなるため、毎回初期化してください。

コードが重要なホットスポットであることが証明されている場合は、一度初期化してからコードをクリーンアップします。

時期尚早の最適化はすべての悪の根源です

于 2012-09-11T10:18:14.760 に答える
5

構造体フィールドはwhileループ内で変更されるため、ループで実行される処理の目的に関係なく、各反復中に構造体フィールドを初期化することは理にかなっています。

ループ内で変更されていなくても、いくつかのフィールドを再初期化するのは問題ないと思います。ただし、どのフィールドが変更されたかを追跡し、次の反復で初期化するときにそれらのフィールドを除外することは、面倒なことです。

別の方法は、初期化値とともに一時的な構造変数を使用し、すべての反復の開始時にそれを割り当てることです。

于 2012-09-11T10:26:40.650 に答える
1

まあ、理想的には、あなたはあなたが取り組んでいる問題を解決する最小限の操作をしたいと思うでしょう。initializationFunctionこのロジックに従って、ループから外し、ループの反復に必要なフィールドを更新する方がよいでしょう。

メンテナンスの観点から、誰かがstructオブジェクトからメンバーをリセットするのを忘れた場合にループ内のアルゴリズムが壊れたり(または奇妙に動作したり)する可能性がある場合は、各ループですべてを初期化することをお勧めします。ただし、これは将来のバグの可能性を排除するものではなく、可能性を低くするだけです。最後に、それはすべてメンテナの能力レベルに依存します。

パフォーマンスの観点からは、これはマイクロ最適化であり、実際には重要ではありません(初期化関数で時間のかかる作業を行わない限り)。

于 2012-09-11T10:29:56.577 に答える
1

それはバランスと複雑さの問題です。構造体のほとんどのメンバーがwhileループでアクセスされない場合、初期化は明らかに不要です...しかし、なぜそれらは構造体内でグループ化されて座っているのでしょうか。彼らの最初の目的は何でしたか?この場合、コード自体は必要以上に複雑ですが、Cのアイドル状態のデータは、実行されていないコードよりももちろん混乱が少なくなります。

OTOHが構造体メンバーの大部分がwhileループで使用されている場合、各メンバーの単なるゼロ割り当てを追加しても、そのメンバーに対する後続のすべての操作は、初期化のパフォーマンスへの影響を多かれ少なかれ軽減するため、それほど害はありません。 nマナー。

コードのメンテナンスに有害だと思うのは、init関数自体が構造体を知る必要があるということです。つまり、必要以上に多くの場所に情報を分散させているということです。IIRC Cでは、構造体をmemsetでnullにすることができ(unsigned charのベクトルとして構造体に触れる)、メンバーは本当に0 ==>これが明らかに間違っている場合は、申し訳ありません。誰かがすべての印刷バージョンを壊す可能性があります。私の頭の上の基準。

于 2012-09-11T10:52:25.157 に答える
1

ループを実行するたびに構造を初​​期化する必要がある場合は、内部で初期化しても問題ありません。ループの前に初期化したダミー構造を使用memcpyして、クリアされた構造をループ内の実際の構造にコピーすることもできます。

または、Steve Jessopによってリンクされた質問に対する受け入れられた回答のように、memcpy通常の割り当てを使用する代わりに、コンパイラにコピーについて心配させます。

于 2012-09-11T10:24:07.860 に答える