std::future 并使用 -stdlib=libstdc++
std::future and clang with -stdlib=libstdc++
以下程序使用 clang 和 -stdlib=libstdc++ link 失败:
$ cat future.cpp
#include <iostream>
#include <future>
int main()
{
std::future<int> f1 = std::async([](){ return 42; });
f1.wait();
std::cout << "Magic number is: " << f1.get() << std::endl;
}
$ g++-mp-5 future.cpp -std=c++11 && ./a.out
Magic number is: 42
$ clang++-mp=3.5 future.cpp -std=c++11 && ./a.out
Magic number is: 42
使用 clang 和 -stdlib=libstdc++ 构建时,出现以下 linking 错误:
$ clang++-mp-3.5 future.cpp -std=c++11 -stdlib=libstdc++ -I/opt/local/include/gcc5/c++ -I/opt/local/include/gcc5/c++/x86_64-apple-darwin14 -L/opt/local/lib/gcc5 -lstdc++ && ./a.out
Undefined symbols for architecture x86_64:
"std::__once_call", referenced from:
void std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) in future-b6480b.o
void std::call_once<void (std::thread::*)(), std::reference_wrapper<std::thread> >(std::once_flag&, void (std::thread::*&&)(), std::reference_wrapper<std::thread>&&) in future-b6480b.o
"std::__once_callable", referenced from:
void std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) in future-b6480b.o
void std::__once_call_impl<std::_Bind_simple<std::_Mem_fn<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*)> (std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*)> >() in future-b6480b.o
void std::call_once<void (std::thread::*)(), std::reference_wrapper<std::thread> >(std::once_flag&, void (std::thread::*&&)(), std::reference_wrapper<std::thread>&&) in future-b6480b.o
void std::__once_call_impl<std::_Bind_simple<std::_Mem_fn<void (std::thread::*)()> (std::reference_wrapper<std::thread>)> >() in future-b6480b.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
但是,一个简单的程序 w/o future
构建起来就很好,例如:
$ cat simple.cpp
#include <iostream>
#include <future>
int main()
{
std::cout << "Magic number is: " << 42 << std::endl;
}
$ clang++-mp-3.5 simple.cpp -std=c++11 -stdlib=libstdc++ -I/opt/local/include/gcc5/c++ -I/opt/local/include/gcc5/c++/x86_64-apple-darwin14 -L/opt/local/lib/gcc5 -lstdc++ && ./a.out
Magic number is: 42
系统是 OSX 10.10.4,带有 macports。
我不知道是什么问题。谢谢!
OSX 上的 Clang 使用旧版本的 libstdc++。我相信它的 4.2 版不支持许多 C++11 功能。如果您想在 OSX 上使用带有 clang 的 C++11,您唯一的选择是 libc++。
您还可以使用自制软件中的 gcc-4.x,它将包含更新版本的 libstdc++。不幸的是,这个版本的标准库不会轻易 link。
这是 GCC 和 Clang 在 Mac OS X 上的不兼容性。
GCC 发出对 ___emutls_v._ZSt15__once_callable
的引用,而 clang 发出对 __ZSt15__once_callable
.
的引用
不幸的是,__ZSt15__once_callable
和 ___emutls_v._ZSt15__once_callable
不兼容,所以做类似的事情:
asm("__ZSt15__once_callable: jmp ___emutls_v._ZSt15__once_callable");
也不行。
我还看到了这个 LLVM 错误报告:http://lists.cs.uiuc.edu/pipermail/llvmbugs/2014-August/035744.html 这可能意味着 clang 永远不会添加支持 GCC 的 emutls 实现。
编辑: 似乎几个小时前在 r243438 中通过 -femulated-tls
.[=18= 将对 emutls 的支持添加到了 clang 主干中]
构建 GCC 的标准库时未定义的符号 std::__once_call
在此处进行了说明 https://github.com/msys2/MINGW-packages/issues/5786,并且在使用编译器标志 -femulated-tls
时应予以修复 -femulated-tls
。
以下程序使用 clang 和 -stdlib=libstdc++ link 失败:
$ cat future.cpp
#include <iostream>
#include <future>
int main()
{
std::future<int> f1 = std::async([](){ return 42; });
f1.wait();
std::cout << "Magic number is: " << f1.get() << std::endl;
}
$ g++-mp-5 future.cpp -std=c++11 && ./a.out
Magic number is: 42
$ clang++-mp=3.5 future.cpp -std=c++11 && ./a.out
Magic number is: 42
使用 clang 和 -stdlib=libstdc++ 构建时,出现以下 linking 错误:
$ clang++-mp-3.5 future.cpp -std=c++11 -stdlib=libstdc++ -I/opt/local/include/gcc5/c++ -I/opt/local/include/gcc5/c++/x86_64-apple-darwin14 -L/opt/local/lib/gcc5 -lstdc++ && ./a.out
Undefined symbols for architecture x86_64:
"std::__once_call", referenced from:
void std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) in future-b6480b.o
void std::call_once<void (std::thread::*)(), std::reference_wrapper<std::thread> >(std::once_flag&, void (std::thread::*&&)(), std::reference_wrapper<std::thread>&&) in future-b6480b.o
"std::__once_callable", referenced from:
void std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) in future-b6480b.o
void std::__once_call_impl<std::_Bind_simple<std::_Mem_fn<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*)> (std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*)> >() in future-b6480b.o
void std::call_once<void (std::thread::*)(), std::reference_wrapper<std::thread> >(std::once_flag&, void (std::thread::*&&)(), std::reference_wrapper<std::thread>&&) in future-b6480b.o
void std::__once_call_impl<std::_Bind_simple<std::_Mem_fn<void (std::thread::*)()> (std::reference_wrapper<std::thread>)> >() in future-b6480b.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
但是,一个简单的程序 w/o future
构建起来就很好,例如:
$ cat simple.cpp
#include <iostream>
#include <future>
int main()
{
std::cout << "Magic number is: " << 42 << std::endl;
}
$ clang++-mp-3.5 simple.cpp -std=c++11 -stdlib=libstdc++ -I/opt/local/include/gcc5/c++ -I/opt/local/include/gcc5/c++/x86_64-apple-darwin14 -L/opt/local/lib/gcc5 -lstdc++ && ./a.out
Magic number is: 42
系统是 OSX 10.10.4,带有 macports。
我不知道是什么问题。谢谢!
OSX 上的 Clang 使用旧版本的 libstdc++。我相信它的 4.2 版不支持许多 C++11 功能。如果您想在 OSX 上使用带有 clang 的 C++11,您唯一的选择是 libc++。
您还可以使用自制软件中的 gcc-4.x,它将包含更新版本的 libstdc++。不幸的是,这个版本的标准库不会轻易 link。
这是 GCC 和 Clang 在 Mac OS X 上的不兼容性。
GCC 发出对 ___emutls_v._ZSt15__once_callable
的引用,而 clang 发出对 __ZSt15__once_callable
.
不幸的是,__ZSt15__once_callable
和 ___emutls_v._ZSt15__once_callable
不兼容,所以做类似的事情:
asm("__ZSt15__once_callable: jmp ___emutls_v._ZSt15__once_callable");
也不行。
我还看到了这个 LLVM 错误报告:http://lists.cs.uiuc.edu/pipermail/llvmbugs/2014-August/035744.html 这可能意味着 clang 永远不会添加支持 GCC 的 emutls 实现。
编辑: 似乎几个小时前在 r243438 中通过 -femulated-tls
.[=18= 将对 emutls 的支持添加到了 clang 主干中]
构建 GCC 的标准库时未定义的符号 std::__once_call
在此处进行了说明 https://github.com/msys2/MINGW-packages/issues/5786,并且在使用编译器标志 -femulated-tls
时应予以修复 -femulated-tls
。