【问题标题】:Uncalled function has effect on outcome of code未调用的函数对代码的结果有影响
【发布时间】:2019-07-18 16:59:12
【问题描述】:

在这里挠头。在下面的代码中,f 函数以 3 种不同的方式使用,分别是 task_lambda()task_bind()task_thread()。然而,在main() 中,只有函数task_lambda()task_bind() 被实际调用和执行。但是,如果您敢取消注释 #if 0 代码块,使得未使用的函数 task_thread() 不再在代码中,那么 main 中的代码现在将抛出异常 (-1) system_error。

代码如下:

#include <iostream>                                                                                                                                                                                         
#include <cmath>
#include <thread>
#include <future>
#include <functional>
#include <unistd.h>

// unique function to avoid disambiguating the std::pow overload set
int f(int x, int y) { return std::pow(x,y); }

void task_lambda()
{
    std::packaged_task<int(int,int)> task([](int a, int b) {
        return std::pow(a, b);
    }); 
    std::future<int> result = task.get_future();

    task(2, 9); 

    std::cout << "task_lambda:\t" << result.get() << '\n';
}

void task_bind()
{
    std::packaged_task<int()> task(std::bind(f, 2, 11));
    std::future<int> result = task.get_future();

    task();

    std::cout << "task_bind:\t" << result.get() << '\n';
}

//#if 0
void task_thread()
{
    std::packaged_task<int(int,int)> task(f);
    std::future<int> result = task.get_future();

    std::thread task_td(std::move(task), 2, 10);
    task_td.detach();
}
//#endif

int main()
{
    task_lambda();
    task_bind();
    sleep(1);
}

这到底是什么意思?

编辑 - 添加工具链信息:

Ubuntu 16.04 - Linux 4.4.0-154-通用

gcc 版本 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.11)

【问题讨论】:

  • 有或没有task_thead,它似乎对我有用。这个问题比代码中显示的要多。尝试干净重建。
  • 可能是其他地方的未定义行为只是以一种新的有趣的方式表现出来。
  • 哪个编译器?
  • -pthread有什么关系。在 G++6.4 下的 https://godbolt.org/ 上崩溃而未通过 -pthread。当与-pthread 链接时工作正常。
  • @Mgetz 和 Mark B 我认为 rafix07 是对的,添加 -pthread fix my repro(fork,单击右侧的齿轮,额外的编译器标志,-pthread)。

标签: c++


【解决方案1】:

编译代码时使用了不正确的链接器标志 -lpthreads 而不是 -pthreads。

一旦使用了 -pthreads 标志,代码现在可以在有或没有未使用的函数的情况下运行。

仍然不确定如果没有未使用的代码,它将如何导致代码无法工作。

【讨论】:

  • 所以 Why 是已知的,如果您查看 OP 上的 cmets,当代码中某处存在未定义行为时,可能会发生这种情况。对于我们这些正在寻找...的人来说,令人担忧的是我们找不到它。所以我们不得不询问编译器开发人员。
猜你喜欢
  • 1970-01-01
  • 2020-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-31
  • 2020-11-12
相关资源
最近更新 更多