配列/構造体のデフォルトで初期化される値について読んでいて、次のような質問があります。
memset(&mystruct, 0, sizeof mystruct)
と同じですかmystruct = { 0 };
?
そうでなければ、何が違うのでしょうか?
ベストアンサー1
memset(&mystruct, 0, sizeof mystruct) は mystruct = { 0 }; と同じですか?
いいえ。
memset(&mystruct, 0, sizeof mystruct) ;
...は、コンパイラに、設定すると予想される関数を呼び出すように指示します。実行中mystruct 内のデータをゼロにします。
mystruct = { 0 };
... は、コンパイラーにデータをゼロに設定するよう指示します。つまり、次のようになります。
- もし可能ならmystructのデータをゼロに設定するコンパイル時(例えば静的変数の場合、トリストピアそしてオリ・チャールズワースコメントで述べた)
- またはそうでなければ(例: 自動変数) を使用して、変数が初期化されるときにデータをゼロに設定するアセンブリ コードを生成します (これを行うには関数を呼び出すよりも優れています)。
ご了承ください多分コンパイラはmemsetをコンパイル時命令に最適化することができる(最初のバージョンを2番目のバージョンに置き換えるようなmemset
) ですが、これはランタイムライブラリの関数であり、言語固有のものではないため、これに頼るつもりはありません(私はコンパイラーライターや言語弁護士ではありませんが)。
C++ 出身の私個人の見解としては、コンパイル時にできることが多ければ多いほど、また実行が始まる前のコンパイル時にコンパイラが知っていることが多ければ多いほど良いということです。コンパイラがコードを最適化したり、警告やエラーを生成したりできるようになるからです。
この場合、mystruct = { 0 };
表記法を使用して初期化する方が、struct
memsetを使用するよりも常に安全です。とてもmemset
コンパイラが文句を言わずに、C で間違ったことを簡単に書くことができます。
次の例は、コードが見た目とは異なる動作を簡単に実行できることを示しています。
// only the 1st byte will be set to 0
memset(&mystruct, 0, sizeof(char)) ;
// will probably overrun the data, possibly corrupting
// the data around it, and you hope, crashing the process.
memset(&mystruct, 0, sizeof(myLARGEstruct)) ;
// will NOT set the data to 257. Instead it will truncate the
// integer and set each byte to 1
memset(&mystruct, 257, sizeof(mystruct)) ;
// will set each byte to the value of sizeof(mystruct) modulo 256
memset(&mystruct, sizeof(mystruct), 0) ;
// will work. Always.
mystruct = { 0 } ;