私たちのコードでは、次のようなものを使用していました。
*(controller->bigstruct) = ( struct bigstruct ){ 0 };
これは以前はうまく機能していましたが、GCC のバージョンをアップグレードしたところ、突然スタック オーバーフローが発生し始めました。アセンブリを見ると、古い GCC コード (2.x) は基本的にこれを行っていました。
memset(controller->bigstruct, 0, sizeof(struct bigstruct));
新しい GCC (3.4.x) はこれを行っていました
struct bigstruct temp = { 0 };
controller->bigstruct = temp;
C99 の仕様を確認したところ、その理由がわかりました。C99 では、基本的に匿名構造体がスタック上に存在する必要があります。これは良いコンセプトですが、この構造体は 4 メガバイトの大きさであり、ヒープ上にのみ存在することを意図していました!
メンバーを明示的に設定する独自の「初期化」関数を作成することにしましたが、これは見苦しく、メンテナンスの頭痛の種です。私は memset を適切な解決策とは考えていません。なぜなら、0 のビット値が型の適切なゼロ値であることを知ることができないからです (ニトピッキング、私は知っていますが、そこにいます;私はそれを気にしませんコンパイラは知っているので、それを行います)
このような大きな構造を初期化する「正しい」、または少なくとも最善の方法は何ですか?
memset が解決策ではないと思う理由をさらに明確にするために、明示的に初期化されていないメンバーの初期化の規則は、静的初期化と同じであり、次のとおりです。 - ポインター型の場合は、null ポインターに初期化されます。- 算術型の場合、(正または符号なし) ゼロに初期化されます。...
「memset」はメモリをビット パターン ゼロに設定しますが、これは必ずしも同じではありません。IEEE 浮動小数点数を使用しないシステムを想像してみてください。珍しいですが、C でサポートされています。0.0 の表現は、「全ビット 0」を意味する必要はなく、プロセッサにとって都合のよいものであれば何でもかまいません。