世の中には怖いもの知らずというか、とんでもないコードを書く人たちがいます。例えば、
| 0 1 2 3 4 5 6 7 8 9 10 11 12 | struct foo {   std::string str;   int a;   int b;   foo()   {     std::memset(this, 0, sizeof(*this));   } }; | 
のようなコードです。さすがにこれはクラッシュする可能性が高いので、実行させてみれば間違いに気付くことでしょう。しかし、こんなのはどうでしょうか?
| 0 1 2 3 4 5 6 7 8 9 10 11 12 | struct bar {   std::pair<long, double> x;   int a;   int b;   bar()   {     std::memset(this, 0, sizeof(*this));   } }; | 
これだと動いてしまう処理系のほうが多そうです。std::pairのようなクラスをstd::memsetでゼロクリアするのはもちろん反則ですので未定義の動作になるわけですが、たまたま動いてしまうわけです。
では、std::stringやstd::pairのようなクラスを一切メンバに持たない、すなわちC互換型だけをメンバに持つような構造体であればコンストラクタでこのようなゼロクリアを行ってもよいのでしょうか?
そんなはずはありませんね。明示的なコンストラクタを定義した時点で、その構造体はもはやC互換構造体ではなくなります。C互換型ではないオブジェクトをstd::memsetでクリアすることはできません。多くの場合は動くかもしれませんが、それはあくまでもたまたまです。メンバの構成が変更されれば実害が出ることも十分考えられるので、こんなコードを書くのは避けるべきです。

![[迷信] アルゴリズム関数内で関数オブジェクトはコピーされない](https://www.kijineko.co.jp/wp-content/uploads/2021/06/4845189_s.jpg)
![[迷信] scanfでキーボードから入力](https://www.kijineko.co.jp/wp-content/uploads/2021/06/4991829_s.jpg)
![[迷信] オブジェクトの動的生成に失敗するとメモリリークする](https://www.kijineko.co.jp/wp-content/uploads/2021/06/4673249_s.jpg)
![[迷信] ソースコード中の即値を全廃せよ](https://www.kijineko.co.jp/wp-content/uploads/2021/06/4167072_s.jpg)
![[迷信] 構造体のタグ名は下線で始める](https://www.kijineko.co.jp/wp-content/uploads/2021/06/4006912_s.jpg)
![[迷信] 実数型とは浮動小数点型のことである](https://www.kijineko.co.jp/wp-content/uploads/2021/06/4011255_s.jpg)