我正在尝试确定libcxxabi在linux下的llvm项目中构建和使用是否有意义.
我的构建libcxxabi与之相关联
ldd libc++abi.so.1.0
linux-vdso.so.1 => (0x00007fff2e0db000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fd658f0d000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fd658d05000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd65893c000)
libc++.so.1 => /path/where/clang/is // edited
/lib64/ld-linux-x86-64.so.2 (0x00007fd6593ab000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fd658465000)
Run Code Online (Sandbox Code Playgroud)
所以它的使用gcc_s图书馆,GNU librt,唯一真正的区别在于它使用的事实libc++了libstdc++,但如何好这真的是什么?
鉴于abi库的关键作用,我应该libcxxabi在这样的平台下去吗?
我的问题不在于如何建立这个,或者如果这样可行,但如果这是一个好主意C++ - 明智的,我可以获得什么样的好处,或者如果你已经使用这个有什么样的好处.
在libc++的实现中std::function,如果要擦除其类型的函数对象足够小以适合 SBO,则移动操作将复制它,而不是移动它。然而,并不是每个堆栈内存占用较小的对象都适合复制。为什么要复制而不是移动?
使用 Clang 考虑这个示例(使用shared_ptr它是因为它具有引用计数):
https://wandbox.org/permlink/9oOhjigTtOt9A8Nt
中的语义与使用显式副本test1()的语义相同。帮助我们看到这一点。test3()shared_ptr
另一方面,GCC 的行为是合理且可预测的:
https://wandbox.org/permlink/bYUDDr0JFMi8Ord6
两者都是标准允许的。std::function要求函数可复制,移出的对象处于未指定状态,等等。为什么要这么做?同样的推理也适用于std::map:如果键和值都是可复制的,那么为什么不每当有人std::movesa时就制作一个新副本std::map?这也符合标准的要求。
根据cppreference.com 的说法,应该有一个举动,并且应该是目标。
这个例子:
#include <iostream>
#include <memory>
#include <functional>
#include <array>
#include <type_traits>
void test1()
{
/// Some small tiny type of resource. Also, `shared_ptr` is used because it has a neat
/// `use_count()` feature that will allow us to see what's going on behind the 'curtains'.
auto foo …Run Code Online (Sandbox Code Playgroud) 这可能非常明显,但为什么boost中的基于流的解析复制了最后一个字母?我一定做错了什么:
#include <iostream>
#include <sstream>
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
int main() {
std::string input = "hello";
std::stringstream ss(input);
std::string r1, r2;
boost::spirit::istream_iterator first(ss), last;
qi::phrase_parse(input.begin(), input.end(), qi::lexeme[qi::alpha >> *qi::alnum], qi::space, r1);
std::cout << r1 << std::endl; // prints "hello"
qi::phrase_parse(first, last, qi::lexeme[qi::alpha >> *qi::alnum], qi::space, r2);
std::cout << r2 << std::endl; // prints "helloo"
}
Run Code Online (Sandbox Code Playgroud)
使用XCode 5.0和Boost 1.54.0进行测试.
编辑: 问题似乎是特定于libc ++.有人使用Clang护理确认吗?
第一对夫妇太长,无法参考.当我尝试clang++ -stdlib=libc++ ../main.cc ...使用SVN中的clang和libc ++ 进行编译时,我收到此错误.
error: undefined reference to 'typeinfo for char const*'
error: undefined reference to '__cxa_allocate_exception'
error: undefined reference to '__cxa_throw'
/tmp/cc-pbn00y.o:../main.cc:function std::__1::deque<double, std::__1::allocator<double> >::__add_back_capacity(): error: undefined reference to '__cxa_begin_catch'
/tmp/cc-pbn00y.o:../main.cc:function std::__1::deque<double, std::__1::allocator<double> >::__add_back_capacity(): error: undefined reference to '__cxa_rethrow'
/tmp/cc-pbn00y.o:../main.cc:function std::__1::deque<double, std::__1::allocator<double> >::__add_back_capacity(): error: undefined reference to '__cxa_end_catch'
/tmp/cc-pbn00y.o(.eh_frame+0xbd3): error: undefined reference to '__gxx_personality_v0'
Run Code Online (Sandbox Code Playgroud)
解决方案:感谢其中一个答案,我知道解决方案.libc ++本身不能像libstdc ++那样使用,它必须与libc ++ abi一起链接.但是,libc ++ abi尚未完成,因此目前使用libc ++似乎有些不完整,但它仍然是我完成时的首选.
更新2012年5月26日: libc ++ abi现在已经完成了C++,我已经成功地使用了clang ++ clang++ -std=c++11 -stdlib=libc++ …
在boost的实现中shared_ptr,它使用宽松的内存排序来增加其引用计数.这似乎是安全的,因为减量使用获取/释放来确保在释放内存之前线程可以看到任何先前的减量.这种方法似乎是正确的,并出现在Herb Sutters 谈论原子论
在libc ++中,实现使用全内存屏障
template <class T>
inline T
increment(T& t) _NOEXCEPT
{
return __sync_add_and_fetch(&t, 1);
}
template <class T>
inline T
decrement(T& t) _NOEXCEPT
{
return __sync_add_and_fetch(&t, -1);
}
} // name
Run Code Online (Sandbox Code Playgroud)
这个决定有理由吗?它们之间是否有任何性能或安全差异?
我有以下代码:
#include <print>
#include <vector>
int main() {
std::vector<int> v{1, 2, 3};
std::println("{}", v);
}
Run Code Online (Sandbox Code Playgroud)
在这产生的众多错误中,有(clang++ -std=c++23 -stdlib=libc++,https://godbolt.org/z/3z9Tseh37):
[...]/format_arg_store.h:167:17: error: static assertion failed due to [...]
167 | static_assert(__arg != __arg_t::__none, "the supplied type is not formattable");
| ^~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
这让我很困惑,因为根据cppreference C++23 编译器支持页面,libc++ 支持std::println并实现P2286: Formatting Ranges。
我做错了什么还是这是标准库错误?
在我的 clang 和 libc++ 版本(near HEAD)中,这static_assert通过了:
static_assert(std::is_copy_constructible_v<std::vector<std::unique_ptr<int>>>)
Run Code Online (Sandbox Code Playgroud)
当然,如果您实际上尝试复制构造唯一指针的向量,它将无法编译:
../include/c++/v1/__memory/allocator.h:151:28: error: call to implicitly-deleted copy constructor of 'std::unique_ptr<int>'
::new ((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
[...]
note: in instantiation of member function 'std::vector<std::unique_ptr<int>>::vector' requested here
const std::vector<std::unique_ptr<int>> bar(foo);
^
../include/c++/v1/__memory/unique_ptr.h:215:3: note: copy constructor is implicitly deleted because 'unique_ptr<int>' has a user-declared move constructor
unique_ptr(unique_ptr&& __u) _NOEXCEPT
Run Code Online (Sandbox Code Playgroud)
我认为这种情况是因为实现在不可复制构造std::vector<T>时不使用 SFINAE 来禁用复制构造函数。T但为什么不呢?标准中是否有规定必须以这种方式工作?这是不幸的,因为这意味着我自己的围绕复制构造性的 SFINAE 并没有在向量方面做正确的事情。
我很难理解为什么这个代码,尝试<random>在C++ 11中使用新的标头,正确地生成随机数[0, 2**62 - 1]而不是[0, 2**63 - 1]或[0, 2**64 - 1].
#include <iostream>
#include <stdint.h>
#include <random>
#include <functional>
#include <ctime>
static std::mt19937 engine; // Mersenne twister MT19937
void print_n_random_bits (unsigned int n);
int main (void) {
engine.seed(time(0));
print_n_random_bits(64);
print_n_random_bits(63);
print_n_random_bits(62);
return 0;
}
void print_n_random_bits (unsigned int n)
{
uintmax_t max;
if (n == 8 * sizeof(uintmax_t)) {
max = 0;
} else {
max = 1;
max <<= n;
} …Run Code Online (Sandbox Code Playgroud) 我clang按照这里的说明从头开始安装.之后,我按照这里的说明安装libc++使用.libsupc++
现在,每当我使用clang和编译和链接程序时libc++,我需要发出如下命令:
clang++ -stdlib=libc++ -Wl,-rpath,/path/to/libcxx/lib <...>
Run Code Online (Sandbox Code Playgroud)
是否有一种方法以libc++默认使用的方式配置/编译clang ,而不必每次都在命令行上指定库和/或路径?放入LD_LIBRARY_PATH它也不是首选选项,也不是使用自定义包装器脚本.
Travis使用Ubuntu Trusty和默认的libc ++版本svn199600.
但是,我想测试不同的(较新的)版本,因为我已经使用不同的clang版本.
我目前的情况.travis.yml如下:
language: generic
dist: trusty
sudo: required
matrix:
include:
- env: CXX=g++-7 CC=gcc-7
addons:
apt:
packages:
- g++-7
sources: &sources
- ubuntu-toolchain-r-test
- llvm-toolchain-precise
- llvm-toolchain-precise-3.9
- llvm-toolchain-precise-3.8
- llvm-toolchain-precise-3.7
- llvm-toolchain-precise-3.6
- sourceline: 'deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-4.0 main'
key_url: 'http://apt.llvm.org/llvm-snapshot.gpg.key'
- env: CXX=g++-6 CC=gcc-6
addons:
apt:
packages:
- g++-6
sources: *sources
- env: CXX=g++-5 CC=gcc-5
addons:
apt:
packages:
- g++-5
sources: *sources
- env: CXX=g++-4.9 CC=gcc-4.9
addons:
apt:
packages:
- g++-4.9
sources: …Run Code Online (Sandbox Code Playgroud)