2

多くのメンバー変数を持つ多くの POD 構造体があります。コンストラクターで各メンバーを初期化する代わりに、単純に memset を使用します。これは C++ で有効ですか?

struct foo
{
    foo() { std::memset(this, 0, sizeof (foo)); }

    int var1;
    float var2;
    double var3;
    // more variables..
};
4

2 に答える 2

3

C++ 標準では、オールビット ゼロがfloatorのトラップ表現である実装が許可されているため、動作することは保証されていませんdouble。したがって、そのような実装でこれらのメンバーを読み取ると、未定義の動作が発生します。

実装がデータ メンバー間に配置するパディング バイトにも同じことが当てはまります。それらを変更すると、未定義の動作になるか、オブジェクトが未定義の状態になり、使用時に未定義の動作になります。どれか忘れました。

ただし、実際には、私が知っているすべての実装で機能します。

他の回答は、クラスが非POD(C ++ 03)および非自明(C ++ 11)であることについて有効な点を示しています。つまり、コンストラクターを削除して別のmemset場所から呼び出したとしても、標準で動作することは保証されませんただし、コンストラクターを削除した場合は、集計の初期化を使用できます。

foo f = {0};

そして、それはすべてのメンバーをゼロ値に初期化します(それがすべてビットゼロで表されているかどうかに関係なく)、保証されています。

于 2013-04-22T11:22:52.797 に答える
2

標準によると、構造体は POD タイプではないため、memset の使用は許可されていません。

9クラス

自明なクラスは、デフォルトのコンストラクタ (12.1) を持ち、非自明なデフォルト コンストラクタを持たず、自明にコピー可能
なクラスです 10 POD struct108 は、自明なクラスと標準レイアウト クラスの両方である非共用体クラスです非 POD 構造体、非 POD 共用体 (またはそのような型の配列) 型の非静的データ メンバーはありません。

あなたのクラスには自明ではないデフォルトのコンストラクターがあるため、もはや自明ではなく、結果として POD タイプではありません。
ほとんどのコンパイラで動作する可能性が高く、保証はありません。

于 2013-04-22T11:21:17.847 に答える