![](/img/trans.png)
[英]Compiling regex program in clang for libstdc++ in C++14 mode causes errors
[英]Issue when compiling libstdc++ with clang
在使用 clang 编译 libstdc++(即 GNU 对 C++ 标准库的实现)时,我注意到了一个问题。 问题是,如果问题得到确认,我应该向谁报告?
当移动分配一个std::vector<X, A<X>>
时会发生这种情况,条件是:
X
的移动构造函数可能会抛出(尽管我正在分配而不是构造);
A<X>
不会在移动赋值上传播,并且源向量和目标向量使用的分配器不比较相等。
一个MCVE紧随其后(现场观看)。 不幸的是,它包含一些样板,最重要的部分由注释指示。
#include <vector>
#include <memory>
#include <type_traits>
struct X {
X() = default;
X(const X&) = default;
// Move constructor might throw
X(X&&) noexcept(false) = default;
// Track calls to assignment functions
X& operator=(const X&) {
putchar('c'); return *this;
}
X& operator=(X&&) noexcept(true) {
putchar('m'); return *this;
}
};
unsigned counter = 0;
template <typename T>
struct A : std::allocator<T> {
template <typename U>
struct rebind { using other = A<U>; };
A() : std::allocator<T>(), id(++counter) {}
// Does not propagate
using propagate_on_container_move_assignment = std::false_type;
// Does not always compare equal
using is_always_equal = std::false_type;
bool operator ==(const A& o) { return id == o.id; }
bool operator !=(const A& o) { return id != o.id; }
unsigned id;
};
int main() {
std::vector<X, A<X>> a(2), rv(2);
a = std::move(rv);
}
据我所知,clang++ 默认使用 libstdc++,使用 libc++ 是通过-stdlib=libc++
选择加入的。 运行上面的代码(同样,使用 clang 和 libstdc++ 构建)显示cc
,这意味着rv
的两个元素被复制分配a
.
但是,引用[container.requirements.general]/4,表 83
“a 的所有现有元素要么被分配到移动,要么被销毁”
( [container.requirements.general]/16, Table 86进一步证实了这一点。)
另一方面,通过将编译器切换到 gcc 或库切换到 libc++,我们得到与上面的引用一致的mm
。 通过将X(X&&)
的异常规范更改为noexcept(true)
也会发生这种情况,而operator =(X&&)
的异常规范似乎无关紧要。
我错过了什么吗? 如果不是,我应该向谁报告问题? 它是 libstdc++ 或 clang。 (我认为这可能并不明显。)我倾向于认为是后者,因为 AFAIK,clang 应该支持 libstdc++ 而不是相反。
(旁注:上面的代码至少可以揭示另一个问题,即从A
中删除rebind
使得 clang/libstdc++ 无法编译,而 clang/libc++ 成功。在我看来,在这种情况下,责任被逆转并落在 libstdc++ 上,但是这不是我的问题的一部分。)
libstdc++ 正在为此使用move_if_noexcept
,它可能不应该这样做。 错误报告应该 go 给他们。
rest 似乎是由于在如何处理具有异常规范不匹配的默认成员 function 方面存在分歧。 这是格式错误的,然后被删除,然后有效。 有关历史,请参阅P1286R2 。
move_if_noexcept
将尝试复制。move_if_noexcept
会认为该类型是 nothrow move 可构造的并尝试移动。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.