【问题标题】:Is std::promise broken on my machine (using g++-mp)?我的机器上的 std::promise 是否损坏(使用 g++-mp)?
【发布时间】:2013-04-03 02:53:16
【问题描述】:

这段代码是否有效,还是我的编译器坏了?

#include <future>
#include <iostream>

int main() {
   std::cout << "doing the test" << std::endl;
   std::promise<bool> mypromise;
   std::future<bool> myfuture = mypromise.get_future();
   mypromise.set_value(true);
   bool result = myfuture.get();
   std::cout << "success, result is " << result << std::endl;
   return 0;
}

这是输出:

$ g++-mp-4.8 -std=c++11 test.cpp
$ ./a.out
doing the test
Segmentation fault: 11
$ 

我正在使用 g++-mp-4.8,它是来自 macports 的 gcc 4.8。

我要疯了吗?

【问题讨论】:

  • 好吧,它在 Ideone 中也崩溃了:ideone.com/wNsr1h。我不太了解这些库,但我猜这可能不是使用它们的正确方法。
  • 在 Linux/g++-4.7.2 上没有段错误,但会抛出 std::system_error
  • 在本地 GCC 4.8 上,我只能在添加 -pthread 命令行选项时才能使其工作(在执行与 std::thread 相关的任何操作时通常需要此选项,可能包括 @987654327 @ 和 std::promise 也是如此)。
  • @Verdagon 我不确定在这种情况下是否有所不同,但该选项实际上应该是-pthread,而不仅仅是链接器选项-lpthread。 (在我的 GCC 上,它不是 g++-mp,但它也适用于 -lpthread。)
  • 尝试运行 otool -L ./a.out 以确保您使用的是 GCC 4.8 中的 libstdc++.dylib 而不是更旧的系统库

标签: c++ gcc c++11 future


【解决方案1】:

动态链接器可能会将您的程序链接到旧版本的libstdc++,即/opt/local/lib/libstdc++.6.dylib 中的那个

由于您使用 GCC 4.8 进行编译,因此您需要使用 GCC 4.8 附带的新 libstdc++,可能是 /opt/local/lib/gcc48/libstdc++.6.dylib

您应该检查/opt/local/lib/libstdc++.6.dylib 是否是GCC 4.8 附带的库,如果不是,请使用正确的库。

您可以通过多种方式控制它,最简单(但不一定是最好的)是运行:

export DYLD_LIBRARY_PATH=/opt/local/lib/gcc48/
./a.out

请参阅http://gcc.gnu.org/onlinedocs/libstdc++/faq.html#faq.how_to_set_pathshttp://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dynamic_or_shared.html#manual.intro.using.linkage.dynamic 了解其他信息(并非特定于 Mac OS X)

【讨论】:

  • 不走运 =\ 确实我有那个文件夹,但是在 ./a.out 之前执行那个导出行并没有导致任何变化。我也在 g++-mp-4.8 调用之前尝试了该行,但那里也没有任何变化......
【解决方案2】:

您的代码在 Xcode 中编译并运行良好。输出是

做测试 成功,结果为 1

编译器是 Apple LLVM 4.2

因此,我建议你有一个编译器配置问题

【讨论】:

  • 你有 c++11 在 xcode 中工作吗?我使用 g++-mp-4.8 的原因是我无法让它工作。你能指出我在哪里学习了如何为 c++11 配置 xcode 吗?
  • OK - 首先我使用的是 XCode 4.6。我不记得我在哪里找到了这些指令,但是转到 Build Options->Compiler: Set it to Apple LLVM compiler 4.2。然后转到C++语言方言并选择GNU++11[-std=gnu++11]
  • 显然答案是错误的。 GCC 4.2(Apple 或其他版本不支持未来/异步)。新的 Xcode 应该能够使用 clang 和 libc++ 编译代码。
  • 嗨永伟 - 你能详细说明什么是“错误”吗?这是我对如何在 xcode 中配置 c++11 的描述吗? OP 没有将任何响应标记为正确 - 所以我不确定你的答案是什么意思。谢谢。
【解决方案3】:

这是一个 MacPorts 错误。 MacPorts 上已经有错误报告。你可以关注那里:

https://trac.macports.org/ticket/38814(主要问题)
https://trac.macports.org/ticket/38833(我的报告,目前标记为#38814的重复)

【讨论】:

    【解决方案4】:

    确认:您的代码在这里产生了同样的问题:

    编译器:g++ -v 给出

     Using built-in specs.
     COLLECT_GCC=/opt/local/bin/g++-mp-4.8
     COLLECT_LTO_WRAPPER=/opt/local/libexec/gcc/x86_64-apple-darwin12/4.8.1/lto-wrapper
     Target: x86_64-apple-darwin12
    

    配置为:../gcc-4.8-20130328/configure --prefix=/opt/local --build=x86_64-apple-darwin12 --enable-languages=c,c++,objc,obj-c++,fortran ,java --libdir=/opt/local/lib/gcc48 --includedir=/opt/local/include/gcc48 --infodir=/opt/local/share/info --mandir=/opt/local/share/man --datarootdir=/opt/local/share/gcc-4.8 --with-local-prefix=/opt/local --with-system-zlib --disable-nls --program-suffix=-mp-4.8 -- with-gxx-include-dir=/opt/local/include/gcc48/c++/ --with-gmp=/opt/local --with-mpfr=/opt/local --with-mpc=/opt/local - -with-ppl=/opt/local --with-cloog=/opt/local --enable-cloog-backend=isl --disable-cloog-version-check --enable-stage1-checking --disable-multilib - -enable-lto --enable-libstdcxx-time --with-as=/opt/local/bin/as --with-ld=/opt/local/bin/ld --with-ar=/opt/local/ bin/ar --with-bugurl=https://trac.macports.org/newticket --with-pkgversion='MacPorts gcc48 4.8-20130328_0'

     Thread model: posix
     gcc version 4.8.1 20130328 (prerelease) (MacPorts gcc48 4.8-20130328_0)
    

    在 gdb 中运行它会得到:

    doing the test
    
    Program received signal EXC_BAD_ACCESS, Could not access memory.
    Reason: 13 at address: 0x0000000000000000
    0x0000000100081c30 in __once_proxy ()
    (gdb) up
    #1  0x00007fff8872fff0 in pthread_once ()
    (gdb) up
    #2  0x0000000100000fd2 in __gthread_once ()
    (gdb) up
    #3  0x00000001000020c9 in _ZSt9call_onceIMNSt13__future_base11_State_baseEFvRSt8functionIFSt10unique_ptrINS0_12_Result_baseENS4_8_DeleterEEvEERbEIKPS1_St17reference_wrapperIS8_ESF_IbEEEvRSt9once_flagOT_DpOT0_ ()
    (gdb) up
    #4  0x0000000100001886 in std::__future_base::_State_base::_M_set_result ()
    (gdb) up
    #5  0x00000001000025ef in std::promise<bool>::set_value ()
    (gdb) up
    #6  0x000000010000119f in main ()
    

    所以这似乎是 libstdc++ 中的一些错误。顺便说一句,使用 clang 3.2(自制软件),它可以编译并运行良好(result is 1)。也许您应该使用 bugzilla 提交错误报告...

    【讨论】:

      【解决方案5】:

      如果您不必使用 GCC,则可以使用最新版本的 Apple 编译器。确保从 Xcode 中安装最新的 Xcode 以及“命令行工具”。

      命令行应该是:

      clang++ -std=c++11 -stdlib=libc++ -pthread test.cpp

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-23
        相关资源
        最近更新 更多