用MinGW gcc/g ++编译的程序中的运行时错误(nuwen distro) [英] Run-time error in program compiled with MinGW gcc/g++ (nuwen distro)

查看:183
本文介绍了用MinGW gcc/g ++编译的程序中的运行时错误(nuwen distro)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

#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;
}

这将编译并运行MSVC,而不会出现问题.它使用gcc编译时没有错误,但是mt19937 gen(rd());行导致程序崩溃,并显示以下消息:

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停止工作

"myprog.exe has stopped working

一个问题导致程序无法正常运行. Windows将关闭该程序,并在解决方案可用时通知您."

A problem caused the program to stop working correctly. Windows will close the program and notify you if a solution is available."

有什么想法吗?

gcc命令:g++ mycode.cpp -fpermissive -s -o myprog.exe

更新: 将-O2添加到编译命令可以使程序运行,尽管这样做是不正确的. 随机"功能不再是随机的.它总是返回1.例如,使用以下主要"代码进行测试...

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;
}

...产生以下输出:<0, 1000>

...yields this output: <0, 1000>

推荐答案

看来这是nuwen发行版的问题. 16.0和16.1版本都会在std :: random_device构造函数上或在值生成期间生成某种类型的Undefined Behavior,有时会导致静默崩溃,但是很难创建一个简约的示例.

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.

当编译的优化级别大于0时,崩溃似乎消失了. 我不会依赖它,因为最有可能的UB仍然存在于某个地方,并且程序可能在最意想不到的地方崩溃.

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.

版本16.0使用GCC 8.1.0,版本16.1使用GCC 8.2.0. 从 https://sourceforge.net/projects/mingw-下载的MinGW,我无法重现此错误. w64/,它也使用8.1.0版本.

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.

此外,请注意,MinGW上的std :: random_device不会提供随机数-它是确定性的,始终提供相同的值.不幸的是,标准允许这样做,我认为这是个大问题.

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.

如果每次运行仅需要不同的值,请考虑使用其他非随机源作为种子,例如C库中的时间.如果您确实需要不确定的值,可以使用nuwen发行版随附的boost :: random :: random_device(与std :: random_device相同的接口).虽然它不是仅标头,所以您需要添加额外的链接:

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

g++ foo.cpp -lboost_random -lboost_system

这篇关于用MinGW gcc/g ++编译的程序中的运行时错误(nuwen distro)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆