- ベストアンサー
構造体の初期化のmemsetの第三引数
memset(&lvitem, 0, sizeof(LVITEM)); memset(&lvitem, 0, sizeof(lvitem)); LVITEMに特化した質問ではなく構造体の初期化について、この2つの書き方によるソース管理やコンパイルでのメリットとデメリットを教えてください。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
(1)memset(&lvitem, 0, sizeof(LVITEM)); この書き方は、構造体LVITEMを初期化しているんだな、と分かりやすい。 (2)memset(&lvitem, 0, sizeof(lvitem)); この書き方はとにかく変数lvitemを初期化するんだな、という感じだが、型が分からないので宣言しているところを参照しなければならない。 それともう一つ、ただ単に何回も初期化するんでなければ、こういう書き方もできる。 (3)LVITEM lvitem = {0}; 結局どれがいいのかといえば、個人的にはケースバイケースですねえ。初期化を1回すればいいような感じなら(3)、構造体名を明示した方が調べる手間がなくなるようなら(1)、そうでなければ(2)を使います。 コンパイルでのメリット、デメリットは特にないんじゃないかなあ。アセンブラがまだ全盛だった頃ならともかく、いまじゃどのコンパイラだって最適化オプションで同じようなコードはくでしょう。 気にするほどでもないと思うけど…
その他の回答 (3)
- z64423
- ベストアンサー率53% (26/49)
1) memset(&lvitem, 0, sizeof(LVITEM)); 2) memset(&lvitem, 0, sizeof(lvitem)); #1 の方の意見に近いですが、 自分がプログラムを書いているときは型と変数を意識していますから あまり間違えないですが、 他人のプログラムを読むときは 2) のほうが読みやすい(親切)です。 少なくとも、memset() を使う際は lvitem の型はどうでもいいことなので、 「lvitem 全体をゼロクリアしてる」ということがすぐ分かりますから。 ※「lvitem の型はホントに LVITEM?」とチェックしなくてよい。 ただし、lvitem がポインタだった場合、 2-a) memset(plvitem, 0, sizeof(*plvitem)); // OK 2-b) memset(plvitem, 0, sizeof(plvitem)); // バグ のように「*」を忘れる可能性があります。 ※ちなみに、sizeof() は関数ではなく演算子なので、 ポインタ plvitem がどんな値でも(NULL でもゴミでも)問題なしです。 実行時ではなく、コンパイル時に解決されるからです。 あと、配列の場合は 2) を使うのですが、 その配列変数が外部変数で extern 参照しているときは 上の 2-b) のパターンなのでバグになります。 extern LVITEM lvitem1[5]; LVITEM lvitem2[5]; memset(lvitem1, 0, sizeof(lvitem1)); // バグ memset(lvitem2, 0, sizeof(lvitem2)); // OK どちらも一長一短という感じですが、 個人的には 2) が好みです。
お礼
1) は型違いの可能性があるから 2) が良いということですね。 ありがとうございました。
- taka_tetsu
- ベストアンサー率65% (1020/1553)
2つの例を 例1 char sz[5]; memset(sz, 0, sizeof(sz)); 配列を初期化したいときは変数を指定しないとだめですよね。 例2 LVITEM * plvItem; plvItem = malloc(sizeof(LVITEM)); memset(plvItem, 0, sizeof(LVITEM)); ポインタ変数の場合、変数のsizeofだとだめですよね。
- phoenix343
- ベストアンサー率15% (296/1946)
#1です。 もう一つ忘れていました。 何か不具合があってデバッグするときに、(1)の書き方していると、本当にlvitemはLVITEMなのか?という疑問がわきます。 その意味では(2)の書き方のほうがバグを出さない書き方、となりそうです。 以上。
お礼
ありがとうございました。
お礼
(3)も可能であるのには気がつきませんでした。 これは宣言と同時にやる場合のみの方法ですね。 ありがとうございました。