多くのメンバー変数を持つ多くの POD 構造体があります。コンストラクターで各メンバーを初期化する代わりに、単純に memset を使用します。これは C++ で有効ですか?
struct foo
{
foo() { std::memset(this, 0, sizeof (foo)); }
int var1;
float var2;
double var3;
// more variables..
};
多くのメンバー変数を持つ多くの POD 構造体があります。コンストラクターで各メンバーを初期化する代わりに、単純に memset を使用します。これは C++ で有効ですか?
struct foo
{
foo() { std::memset(this, 0, sizeof (foo)); }
int var1;
float var2;
double var3;
// more variables..
};
C++ 標準では、オールビット ゼロがfloat
orのトラップ表現である実装が許可されているため、動作することは保証されていませんdouble
。したがって、そのような実装でこれらのメンバーを読み取ると、未定義の動作が発生します。
実装がデータ メンバー間に配置するパディング バイトにも同じことが当てはまります。それらを変更すると、未定義の動作になるか、オブジェクトが未定義の状態になり、使用時に未定義の動作になります。どれか忘れました。
ただし、実際には、私が知っているすべての実装で機能します。
他の回答は、クラスが非POD(C ++ 03)および非自明(C ++ 11)であることについて有効な点を示しています。つまり、コンストラクターを削除して別のmemset
場所から呼び出したとしても、標準で動作することは保証されません。ただし、コンストラクターを削除した場合は、集計の初期化を使用できます。
foo f = {0};
そして、それはすべてのメンバーをゼロ値に初期化します(それがすべてビットゼロで表されているかどうかに関係なく)、保証されています。
標準によると、構造体は POD タイプではないため、memset の使用は許可されていません。
自明なクラスは、デフォルトのコンストラクタ (12.1) を持ち、非自明なデフォルト コンストラクタを持たず、自明にコピー可能
なクラスです 10 POD struct108 は、自明なクラスと標準レイアウト クラスの両方である非共用体クラスです非 POD 構造体、非 POD 共用体 (またはそのような型の配列) 型の非静的データ メンバーはありません。
あなたのクラスには自明ではないデフォルトのコンストラクターがあるため、もはや自明ではなく、結果として POD タイプではありません。
ほとんどのコンパイラで動作する可能性が高く、保証はありません。