首页 > 解决方案 > std::to_chars 在 MacOS / clang 上编译但不链接

问题描述

我在 MacOS 下使用 clang 编译项目时遇到问题。

我确实“查明”了charconv标题内部的问题:

#include <charconv>
#include <array>
#include <iostream>

int main(){
    std::array<char, 64> buffer;

    auto[p, ec] = std::to_chars(buffer.begin(), buffer.end(), 123);

    if (ec != std::errc() )
        std::cout << "error" << '\n';

    std::cout << (const char *) buffer.data() << '\n';
}

这是我的编译方式。

Nikolays-MacBook-Air:~ nmmm$ clang --version
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.5.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

Nikolays-MacBook-Air:~ nmmm$ clang -std=c++17 x.cc -lstdc++
Undefined symbols for architecture x86_64:
  "std::__1::__itoa::__u32toa(unsigned int, char*)", referenced from:
      std::__1::__itoa::__traits_base<unsigned int, void>::__convert(unsigned int, char*) in x-9b1746.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Nikolays-MacBook-Air:~ nmmm$ 

任何帮助将不胜感激。

更新

我试过 clang++,但它给了我同样的错误信息。

标签: c++macosclang++llvm-clangundefined-symbol

解决方案


<charconv>头包含 的声明和使用std::__1::__itoa::__u32toa,一个未在该标头中定义的函数。该函数在 中定义libc++.dylib但是,Applelibc++.dylib的发布频率与其发布标头的频率不同;而且,可能更重要的是,libc++ 直到 2018-09-23 才将新符号包含在 Apple 的“abilist”中,即使标题更改发生在 2018-08-01。因此,在大约 53 天的时间里,libc++ 的(这方面)在 OSX 上不起作用。也许苹果在那段时间把它捡起来并发货了。

使您的代码工作的一种方法是自己构建 libc++。此处的说明,截至 2019 年底。

$ clang++ -std=c++17 test.cc $ROOT/llvm-project/build/lib/libc++.dylib \
    -Wl,-rpath,$ROOT/llvm-project/build/lib
$ ./a.out
123

您的问题的一些评论者建议您可以通过使用 GNU libstdc++ 而不是 LLVM libc++ 来使您的代码工作。这有点模糊,但我怀疑为 OSX 构建 libstdc++ 会比为 OSX 构建 libc++ 更难。(而后者并不简单!)我不知道在 OSX 上安装 libstdc++ 的任何方法。有brew install gcc@8,但我敢打赌 GCC 8 也没有<charconv>

截至 2020 年初,没有供应商(最近微软除外)提供了<charconv>浮点的完整实现to_charsfrom_chars结果证明是困难的,因此大多数供应商不提供它们。(“他们为什么不直接复制现有的实现?”好吧,事实证明,<charconv>在任何实现存在之前,它就被标准化为 C++17 的一部分。没有人猜到这会很困难!


推荐阅读