Portability of random number generation in C++ is also described in this blog post: <a href="http://anadoxin.org/blog/c-shooting-yourself-in-the-foot-4.html" rel="nofollow">http://anadoxin.org/blog/c-shooting-yourself-in-the-foot-4.h...</a>
The generator/seeding design is gnarly, totally agreed.<p>I do want to disagree with the author on distributions. In most scenarios it is totally sufficient for distributions to be deterministic and reproducible on a given implementation/architecture instead of ossifying them to one implementation mandated by the standard.
std::seed_seq and the SeedSeq concept look incredibly broken, also it looks way over-engineered. Why can't a random generator engine just get a Calleable as a constructor argument and call it as many times as it needs to seed itself? SeedSeq tries to be way more than it needs to be while failing its basic requirement.
PCG is not the only game in town when it comes to high-quality reproducible and fast PRNGs: <a href="https://github.com/lemire/testingRNG#visual-summary" rel="nofollow">https://github.com/lemire/testingRNG#visual-summary</a> Notably, some newer PRNGs are faster, and still pass all statistical tests.
My anecdote with C++'s RNGS:
I was getting different sequences of random values using
std::minstd_rand on arm64 and arm32.<p>Turns out it was because the seed type is uint_fast32_t and I was passing a 64 bit seed.
On arm32 the seed was getting truncated to 32 bits, but not on arm64. It was my fault but it was still surprising.
So you need a large stream of random numbers to seed your random number generator? Seems like a bizarre chicken and egg problem... If I <i>had</i> a source for large quantities of random numbers, why would I even need the second random number generator?
By default with gcc and clang on Linux, random_engine will use /dev/urandom.<p>I use /dev/random and configured it with rng-tools. With rng-tools you can configure the sources of entropy for rngd.<p>You can add a hw random number as entropy source there. Just do not add more entropy than the size of the entropy pool or your system performance will suffer.<p>Some people discard a number of generated values to make it harder to guess the internal state of the generator. discard_block_engine can be used for this too.<p>Anyways, if you want to test your random numbers try <a href="https://webhome.phy.duke.edu/~rgb/General/dieharder.php" rel="nofollow">https://webhome.phy.duke.edu/~rgb/General/dieharder.php</a>
One thing that isn't mentioned in the article is performance.<p>C++ standard PRNG's, on top of all the brokenness listed in the article are very inefficient, especially if you use distributions.
You can't even count on std::random_device doing something sane. <a href="https://stackoverflow.com/q/18880654/5987" rel="nofollow">https://stackoverflow.com/q/18880654/5987</a>
> every single part of it is deeply flawed, and the best solution is to avoid using it completely<p>You can sadly say the same for a large part of C++ standard features. At least the core language is mostly sound, simple intuitive and performant, so having to file off some edges is not that big of a problem.