获取指向成员 std::string::size 的指针无法与 libc++ 链接,但可以与 libstdc++ 一起使用

2023-12-19

我正在做一个需要使用 libc++ 的项目。我遇到了以下问题:

当我尝试编译以下代码时:

#include <string>
int main()
{
    std::string::size_type (std::string::*function)() const = &std::string::size;
    return 0;
}

我收到以下错误:

ld:未找到架构 x86_64 的符号

如果我使用 libstdc++ 而不是 libc++,我不会收到任何错误,因此问题应该与 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 http://clang-developers.42468.n3.nabble.com/LIBCPP-INLINE-VISIBILITY-and-std-string-length-td4030879.html其做了类似的事情,Howard Hinnant 的回应是:

我相信这是由于编译器之间的交互不良造成的 外部模板和 __attribute__ ((__always_inline__))。如果 std::string 没有声明为 extern template,那么编译器会 概述一个 size() 成员,您将不会收到此链接错误。

在我看来,clang 不应该假设外部模板有 内联成员的定义,尤其是那些标记的 always_inline,事实上它确实是一个 clang bug,导致 您看到的链接错误。

在libc++中使用always_inline的基本原理是控制 libc++ 的 ABI。过去我见过编译器使用不同的 制作内联/大纲时从一个版本到另一个版本的启发式方法 决定。这可能会导致代码被静默添加和删除 来自 dylib。通过使用always_inline,我告诉 编译器永远不会将该代码添加到 libc++.dylib 二进制文件中。

libc++ 定义和使用的每个宏都可以被覆盖。

_LIBCPP_INLINE_VISIBILITY 控制内联函数的归属方式,默认为:

#ifndef _LIBCPP_INLINE_VISIBILITY
#define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__visibility__("hidden"), __always_inline__))
#endif

您可以通过以下方式关闭此功能:

-D_LIBCPP_INLINE_VISIBILITY=""

外部模板是通过以下方式完成的:

#ifndef _LIBCPP_EXTERN_TEMPLATE
#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
#endif

后一种更难“关闭”。咒语是:

-D'_LIBCPP_EXTERN_TEMPLATE(...)='

使用其中一个(或两个)解决方法将使您的链接静音 错误。但从长远来看,针对 clang 的错误报告可能会更好 解决方案。

我无法重现这个coliru http://coliru.stacked-crooked.com/但我可以wandbox http://melpon.org/wandbox/permlink/85cHKaoAMcIGEa6X并使用优化-O2标志使问题消失。我无法让 wandbox 接受-D上面建议的选项,所以不确定这是否有效。

在我的本地计算机上,霍华德的解决方案有效:

clang++ -D_LIBCPP_INLINE_VISIBILITY="" -D'_LIBCPP_EXTERN_TEMPLATE(...)='

我还没有找到错误报告,如果我没有找到错误报告,那么提交一份可能是有意义的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

获取指向成员 std::string::size 的指针无法与 libc++ 链接,但可以与 libstdc++ 一起使用 的相关文章

随机推荐