Background:
Since c++11, it is recommended to use a std::random_device instead of the time to seed a random number generator. If we take a look at the related documentation, we can read that:
std::random_devicemay be implemented in terms of an implementation-defined pseudo-random number engine if a non-deterministic source (e.g. a hardware device) is not available to the implementation. In this case eachstd::random_deviceobject may generate the same number sequence.
emphasis mine
Let's now consider the following example:
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution distr(0, 9);
// Print a sequence of 10 uniformly distributed random integers
for(std::size_t i = 0; i < 10; ++i)
std::cout << distr(gen) << ' ';
return 0;
}
If the system/platform does not provide a non-deterministic source, this program may/will always generate the same sequence of numbers for each run (it is actually the case on my platform).
In this case, std::random_device is far worse than seeding the random number generator with the current time:
std::mt199937 gen(std::chrono::high_resolution_clock::now().time_since_epoch().count()); // time seed
Issue:
My concern is that if someone wants to write a program that will rely on some random generated numbers and is required:
- To be portable
- To guarantee non-deterministic randomness
Then std::random_device will not be a right fit.
On the other hand, using always a time seed would be a quite frustrating "solution" since if the given platform has a non-deterministic source available, std::random_device would then be "safer".
Question:
My question is divided in two parts:
- Userland
- Is there a portable way to check if such a non-deterministic source is available on the current platform?
- Compiler-side
- Are compilers allowed to replace
std::random_deviceseeds by time seeds if the host platform has no non-deterministic source available ? Or is there something in the standard that would prevent such a replacement? - If the standard does not prohibit this behaviour, what would be a reason for compilers to not implement it?
- Are compilers allowed to replace
Perhaps these should be 2 or 3 separate questions. Since the background and issue are common, I've asked them in the same post for completeness purposes on the topic. Please let me know if I have to split them into separate questions anyway.