0
#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>

Makaveli84
  • 453
  • 6
  • 16
  • Maybe share the crash message? – The Quantum Physicist Jan 04 '19 at 16:45
  • I tried multiple GCC versions in wandbox.org -- no crashes – C.M. Jan 04 '19 at 16:46
  • @TheQuantumPhysicist 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. – Makaveli84 Jan 04 '19 at 16:47
  • Please post the code that calls the function, and all `#include`s needed in order to compile it. –  Jan 04 '19 at 16:49
  • @NeilButterworth I tried but SO complained about my post being mostly code and that I should add more details... – Makaveli84 Jan 04 '19 at 17:02
  • @NeilButterworth Done. Post updated with a "scaled down" version that delineates the problem. – Makaveli84 Jan 04 '19 at 17:08
  • After removing the syntax error, [cannot duplicate](http://coliru.stacked-crooked.com/a/3192b0891a344193) – PaulMcKenzie Jan 04 '19 at 17:10
  • @PaulMcKenzie It's just a syntax eye sore with `-fpermissive` – Makaveli84 Jan 04 '19 at 17:14
  • Don't use -fpermissive. And I cannot reproduce on Windows 10 with nuwen GCC 8.1.0. –  Jan 04 '19 at 17:17
  • Adding `-O2` to the compiling command eliminates the error but leads to a wrong result. The "random" function is no longer random: it always generates a 1. – Makaveli84 Jan 04 '19 at 17:29
  • Time to fire up your debugger! – Lightness Races in Orbit Jan 04 '19 at 17:33
  • _"I tried but SO complained about my post being mostly code and that I should add more details..."_ Then add more details rather than removing important code ^_^ – Lightness Races in Orbit Jan 04 '19 at 17:35
  • I did not remove "important code". It also posted successfully upon reloading in a a different browser tab with the exact same post (scaled down code + details) that it had complained about in prior. This was a SO bug. ^_^ – Makaveli84 Jan 04 '19 at 17:35
  • 1
    Be aware that GCC has historically had issues with `std::random_device` on Windows - it may always produce the same non-random number. Which GCC version number are you using? –  Jan 04 '19 at 17:36
  • g++ (GCC) 8.2.0 / gcc (GCC) 8.2.0 – Makaveli84 Jan 04 '19 at 17:42
  • 3
    Side note: You probably don't need to or want to reseed the random number generator every time you call `randomBit` – user4581301 Jan 04 '19 at 18:34
  • `myclass::myclass() = delete;` is an error, g++ should reject this if you're compiling in standard mode – M.M Jan 16 '19 at 00:36
  • Please give exact version of g++ (I could not reproduce the crash with `7.3.0 (Rev2, Built by MSYS2 project)`, target `i686-w64-mingw32`) – M.M Jan 16 '19 at 00:39

1 Answers1

1

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

Kaznov
  • 1,035
  • 10
  • 17