Reputation: 494
#include <iostream>
#include <random>
using namespace std;
class myclass
{
private:
static bool randomBit()
{
std::random_device rd; // Obtain a random seed number from hardware
std::mt19937 gen(rd()); // Initialize and seed the generator <---- CRASH!!
uniform_int_distribution<> distr(0, 1); // Define the distribution range
return distr(gen);
}
myclass::myclass() = delete; // Disallow creating an instance of this object
public:
static bool generateRandomBit()
{
return randomBit();
}
};
int main()
{
cout<<myclass::generateRandomBit()<<endl;
return 0;
}
This compiles and runs without problems with MSVC. It compiles without errors with gcc
but the mt19937 gen(rd());
line causes the program to crash with the following message:
"myprog.exe has stopped working
A problem caused the program to stop working correctly. Windows will close the program and notify you if a solution is available."
Any ideas?
gcc command: g++ mycode.cpp -fpermissive -s -o myprog.exe
UPDATE:
Adding -O2
to the compiling command gets the program to run, albeit incorrectly so. The "random" function is no longer random; it always returns 1. For example, testing with the following "main" code...
int main()
{
int a[2] {0, 0};
for (int i = 0; i < 1000; i++) {
a[myclass::generateRandomBit()]++;
}
cout<<"<"<<a[0]<<", "<<a[1]<<">"<<endl;
return 0;
}
...yields this output: <0, 1000>
Upvotes: 0
Views: 740
Reputation: 1163
It appears that this is a problem with nuwen distro. Both 16.0 and 16.1 versions generate some kind of Undefined Behavior on std::random_device constructor or during value generation, what sometimes results in silent crash, but it is hard to create a minimalistic example.
Crashes seem to disappear, when code is compiled with optimization level greater than 0. I wouldn't depend on it, as most likely UB still exists there somewhere, and program can crash in the most unexpected places.
Version 16.0 uses GCC 8.1.0 and 16.1 uses GCC 8.2.0. I couldn't reproduce this bug with MinGW downloaded from https://sourceforge.net/projects/mingw-w64/, that uses 8.1.0 version too.
Also, mind that std::random_device on MinGW won't provide random numbers - it will be deterministic, always giving the same values. Unfortunately standard allows it, what is in my opinion a big issue.
If you just need different values with each run, consider seeding with other, not-random sources, like time from C library. If you really need non-deterministic values, you can use boost::random::random_device (same interface as std::random_device), provided with nuwen distro. It is not header-only though, so you need to add extra linking:
g++ foo.cpp -lboost_random -lboost_system
Upvotes: 1