我在一个需要使用libc ++的项目中.我提出了以下问题:
I'm on a project where I need to use libc++. I'm come up with the following problem:
当我尝试编译以下代码时:
When I try to compile the following code:
#include <string> int main() { std::string::size_type (std::string::*function)() const = &std::string::size; return 0; }我收到以下错误:
ld:架构x86_64找不到符号
ld: symbol(s) not found for architecture x86_64
如果我使用libstdc ++而不是libc ++,则不会出现任何错误,因此该问题应该与libc ++有关.
If I use the libstdc++ instead of libc++ I get no errors so the issue should to be related with libc++.
完整的输出如下:
clang++ --stdlib=libc++ -v main.cpp Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn) Target: x86_64-apple-darwin14.1.0 Thread model: posix "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.10.0 -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -main-file-name main.cpp -mrelocation-model pic -pic-level 2 -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu core2 -target-linker-version 241.9 -v -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.0 --stdlib=libc++ -fdeprecated-macro -fdebug-compilation-dir /Users/filipe/Downloads -ferror-limit 19 -fmessage-length 197 -stack-protector 1 -mstackrealign -fblocks -fobjc-runtime=macosx-10.10.0 -fencode-extended-block-signature -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -vectorize-slp -o /var/folders/8k/34ll5dcj3c5c9sph_bwk1zr00000gn/T/main-5b89bb.o -x c++ main.cpp clang -cc1 version 6.0 based upon LLVM 3.5svn default target x86_64-apple-darwin14.1.0 ignoring nonexistent directory "/usr/include/c++/v1" #include "..." search starts here: #include <...> search starts here: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1 /usr/local/include /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.0/include /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include /usr/include /System/Library/Frameworks (framework directory) /Library/Frameworks (framework directory) End of search list. "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" -demangle -dynamic -arch x86_64 -macosx_version_min 10.10.0 -o a.out /var/folders/8k/34ll5dcj3c5c9sph_bwk1zr00000gn/T/main-5b89bb.o -lc++ -lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.0/lib/darwin/libclang_rt.osx.a Undefined symbols for architecture x86_64: "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::size() const", referenced from: _main in main-5b89bb.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)推荐答案
此线程看起来像一个libc++错误: _ LIBCPP_INLINE_VISIBILITY和std :: string :: length 与此类似,霍华德·海因南特的回应是:
This looks like a libc++ bug by this thread: _LIBCPP_INLINE_VISIBILITY and std::string::length which doing something similar and Howard Hinnant's response is:
我相信这是由于编译器之间的不良交互 extern模板和__attribute__((__always_inline__)).如果 未声明std :: string extern模板,则编译器将 概述一个size()成员,您将不会遇到此链接错误.
I believe this is due to a poor interaction in the compiler between extern templates and __attribute__ ((__always_inline__)). If std::string is not declared extern template, then the compiler will outline a size() member and you won't get this link error.
我认为,clang不应该假设extern模板具有 内联成员的定义,尤其是标记的成员 always_inline,并且这样做的事实是导致错误的clang错误 您看到的链接错误.
In my opinion, clang should not assume that extern templates have definitions for inlined members, especially those marked always_inline, and the fact that it does is a clang bug resulting in the link error you see.
在libc ++中使用always_inline的基本原理是控制 libc ++的ABI.过去我看过编译器使用不同的 进行内联/外联时从发布到发布的启发式搜索 决定.这可能会导致代码被静默添加和删除 来自dylib.通过使用always_inline,我告诉 编译器永远不要将该代码添加到libc ++.dylib二进制文件中.
The rationale for the use of always_inline in libc++ is to control the ABI of libc++. In the past I have watched compilers use different heuristics from release to release on making the inline/outline decision. This can cause code to be silently added to and removed from a dylib. With the use of always_inline, I am telling the compiler to never add that code to the libc++.dylib binary.
libc ++定义和使用的每个宏都可以被覆盖.
Each of the macros defined and used by libc++ can be overridden.
_LIBCPP_INLINE_VISIBILITY控制内联函数的属性方式,默认设置为:
_LIBCPP_INLINE_VISIBILITY controls how an inlined function is attributed and defaults to:
#ifndef _LIBCPP_INLINE_VISIBILITY #define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__visibility__("hidden"), __always_inline__)) #endif您可以使用以下方法将其关闭:
You can turn this off with:
-D_LIBCPP_INLINE_VISIBILITY ="
-D_LIBCPP_INLINE_VISIBILITY=""
外部模板通过以下方式完成:
And extern templates are done with:
#ifndef _LIBCPP_EXTERN_TEMPLATE #define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__; #endif后一个更难关闭".该咒语是:
This latter one is more difficult to "turn off". The incantation is:
-D'_LIBCPP_EXTERN_TEMPLATE(...)='
-D'_LIBCPP_EXTERN_TEMPLATE(...)='
使用这些解决方法中的任何一个(或两个)都会使您的链接静音 错误.但是针对clang的错误报告可能是一个更好的长期选择 解决方案.
Using either (or both) of these workarounds will silence your link error. But a bug report against clang might be a better long term solution.
我无法在 coliru 上重现此内容,但可以在 wandbox 并使用使用-O2标志的优化可以解决问题.我无法让wandbox接受上面建议的-D选项,因此不确定是否可行.
I can not reproduce this on coliru but I can on wandbox and using optimization which uses the -O2 flag makes the problem go away. I was not able to make wandbox accept the -D options suggested above, so not sure if that works.
霍华德的解决方案在我的本地计算机上工作
On my local machine Howard's solution works:
clang++ -D_LIBCPP_INLINE_VISIBILITY="" -D'_LIBCPP_EXTERN_TEMPLATE(...)='我没有找到错误报告,如果找不到,则可以提交错误报告.
I have not found a bug report, if I don't find one it may make sense to file one.
更多推荐
获取指向成员std :: string :: size的指针无法与libc ++链接,但可以与libstdc ++一起使用
发布评论