优化级别为-O2的boost :: any_range导致崩溃 [英] 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 .
但是当我以较低的优化级别进行编译时,一切都很好.
But when I compile with lower optimization level, then everything is ok.
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
的错误,还是我滥用了库?
Is this boost::any_range
bug, or I misuse the library?
如果我这样编译,程序也会崩溃:
Program also crashes if I compile it this way:
c++ -g -std=c++14 -O1 -fisolate-erroneous-paths-dereference main.cpp
如果我使用选项 -O1 -fisolate-erroneous-paths-dereference
进行编译,下面的程序也会崩溃:
The program below crashes too, if I compile it with options -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错误10493 ,与 10360 有关,该错误于1.56中引入(2014-08),并最终在修复PR#94
This is boost bug 10493, related to 10360, which was introduced in 1.56 (2014-08) and was only finally fixed in 1.74 (2020-08) via fix PR #94
直到1.74,问题在于它不仅仅使用 reference
类型,而是将其包装在 mutable_reference_type_generator
中,这使您无法返回临时变量.也就是说,当您编写:
Until 1.74, the problem is that instead of just using your reference
type, it wraps it in mutable_reference_type_generator
, which prevents you from being able to return a temporary. That is, when you write:
using Range =
boost::any_range<
int,
boost::forward_traversal_tag,
int,
std::ptrdiff_t>;
您将您的 reference
类型明确指定为 int
,而不是 int&
,因为您的范围基本上是一个输入范围.但是无论如何,boost内部将其更改为 int&
,所以您会晃来晃去.当您编写 int
的 const int
intsead时,类型trait不会添加引用,因此实际上确实以 const int
结尾.
You're explicitly specifying your reference
type to be int
, not int&
, because your range is basically an input range. But the boost internals are changing it to int&
anyway, so you dangle. When you write const int
intsead of int
, the type trait doesn't add the reference, so you actually do end up with const int
.
这篇关于优化级别为-O2的boost :: any_range导致崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!