少し前まで、MinGWのg++ (libstdc++)ではstd::random_deviceが疑似乱数生成器で実装されていて、デフォルトコンストラクタを使うと毎回同じ乱数列が生成される、という困った挙動でした。
- gccをwindowsで使うならstd::random_deviceを使ってはいけない – Qiita
- [C++] Windows環境でmt19937の初期化にrandom_deviceを使うと実行毎に同じ乱数列が生成される問題 – Qiita
これが以下のコミットで最近解決されたようです。時期的にGCC 9.2から入っている様子です。このコミット、Gitリポジトリのtagのgcc-9_1_0-releaseにはなく、gcc-9_2_0-releaseに入っていることを見て確かめました。
- gcc.gnu.org Git – gcc.git/commit
- PR libstdc++/85494 use rdseed and rand_s in std::random_device · gcc-mirror/gcc@91df033 · GitHub
これにより、MinGWではmsvcrt.dllのrand_s関数を使った実装になっています。また、このときプリプロセッサ定数_GLIBCXX_USE_CRT_RAND_S
が定義されるようです。これで、MinGWでも暗号論的に安全で非決定論的な乱数生成器としてrandom_deviceを使えるようになりました。
実際、cpprefjpのサンプルコードをMinGWのg++でコンパイル・実行すると、毎回異なる値が出力される結果が見られます。
なお、c++ – std::random_deviceが生成する数値列が毎回同じなのはOK? – スタック・オーバーフローのalphaさんのコメントで指摘されているCygwinの場合と同様、entropyメンバー関数は0.0を返すようになっていました。
というわけで、MinGWでstd::random_deviceが使い物になるようになりました。MinGWで古いバージョンのGCCを使っているかたは、ぜひ9.2以降にバージョンアップしましょう。
スポンサード リンク |
この記事のカテゴリ
- C++ ⇒ MinGWのrandom_deviceがちゃんとしたものになった