我在使用clang的MacOS下编译项目时遇到问题。
我确实在“ 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 ++,但是它给出了相同的错误消息。
答案 0 :(得分:1)
<charconv>
标头包含std::__1::__itoa::__u32toa
的声明和使用,该标头中未定义函数。该功能在libc++.dylib
中定义。 但是,Apple不会以与运送标头相同的频率运送libc++.dylib
;甚至更重要的是libc++ failed to include the new symbol in its "abilist" for Apple until 2018-09-23,即使the header change landed on 2018-08-01也是如此。因此,大约有53天的时间,libc ++的这一方面在OSX上不起作用。也许苹果在那段时间把它捡起来并发货了。
使代码工作的一种方法是自己构建libc ++。 Instructions here, as of late 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年初, no 供应商(except just recently Microsoft)提供了<charconv>
的完整实现-浮点数to_chars
和from_chars
事实证明这很困难,因此大多数供应商都不提供它们。 (“为什么不复制现有的实现?”好吧,事实证明,<charconv>
在任何实现都存在之前就已作为C ++ 17的一部分进行了标准化。没有人猜测这会很困难! )
答案 1 :(得分:0)
我为此写了一个很长的答案,然后检查并确定它对我有用(在Linux上为clang 9.0.0)。您使用clang
而不是clang++
进行编译。下面的答案很长:
Clang的libc ++长时间未完全实现“基本字符串转换,修订版5”(如to_chars
和from_chars
中一样),并且某些部分仍然很出色,请参阅here 。但是我认为您应该可以使用,因此也许您应该更新库。
要使用to_chars
,请考虑使用它在字符串末尾显式添加 no \0
。因此,您不能仅使用std::cout << (const char *) buffer.data();
。您必须使用指针(在代码中命名为p
)来标记字符串的结尾。通过插入\0
,使用std::string_view sv(buffer.data(), static_cast<size_t>(p-buffer.data());
生成std::copy(buffer.begin(), p, std::ostream_iterator<char>(std::cout, ""));
或其他太多方法。