[英]boost::any_range with optimization level -O2 causes crash
这段代码有什么问题:
#include <iostream>
#include <vector>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/any_range.hpp>
using namespace boost::adaptors;
using Range =
boost::any_range<
int,
boost::forward_traversal_tag,
int,
std::ptrdiff_t>;
void magic(const Range &) {}
int main()
{
std::vector<int> xs{0, 1, 2};
auto ys = xs | transformed([](auto x) { return x; });
const Range zs = ys;
std::vector<int> us{boost::begin(zs), boost::end(zs)};
magic(us);
return 0;
}
符合:
c++ -g -std=c++14 -O2 main.cpp
运行并获取segfault 。
但是当我以较低的优化级别进行编译时,一切正常。
gdb
输出:
Program received signal SIGSEGV, Segmentation fault.
0x00000000004011a5 in boost::range_detail::any_iterator<int, boost::iterators::forward_traversal_tag, int, long, boost::any_iterator_buffer<64ul> >::dereference (this=<optimized out>) at /usr/include/boost/range/detail/any_iterator.hpp:512
512 return m_impl->dereference();
这是boost::any_range
错误,还是我滥用了库?
如果我这样编译程序也会崩溃:
c++ -g -std=c++14 -O1 -fisolate-erroneous-paths-dereference main.cpp
下面的程序也会崩溃,如果我使用选项-O1 -fisolate-erroneous-paths-dereference
编译它:
#include <iostream>
#include <vector>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/any_range.hpp>
using namespace boost::adaptors;
using Range =
boost::any_range<
int,
boost::forward_traversal_tag,
int &,
std::ptrdiff_t>;
void magic(const Range &xs) {
for (auto x: xs) { std::cout << xs; }
}
int main()
{
std::vector<int> xs{0, 1, 2};
auto ys = xs | transformed([](auto x) { return x; });
magic(ys);
return 0;
}
这是boost bug 10493 ,与10360相关,它是在 1.56 (2014-08) 中引入的,并且最终通过修复 PR #94在1.74 (2020-08) 中修复
在 1.74 之前,问题在于它不是只使用您的reference
类型,而是将其包装在mutable_reference_type_generator
,这会阻止您返回临时类型。 也就是说,当你写:
using Range =
boost::any_range<
int,
boost::forward_traversal_tag,
int,
std::ptrdiff_t>;
您明确指定您的reference
类型为int
,而不是int&
,因为您的范围基本上是一个输入范围。 但是无论如何,boost 内部结构正在将其更改为int&
,因此您悬而未决。 当您编写const int
intsad of int
,类型特征不会添加引用,因此您实际上最终得到了const int
。
实际上,当我为我的问题输入标题时, 这个问题是作为可能的答案提供的。
正如答案的问题的建议,我代替int
用const int
和它的工作:
using Range =
boost::any_range<
int,
boost::forward_traversal_tag,
const int,
std::ptrdiff_t>;
我决定发布这个问题,因为引用的问题没有标记为已回答。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.