繁体   English   中英

boost::any_range 优化级别为 -O2 导致崩溃

[英]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 #941.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

实际上,当我为我的问题输入标题时, 这个问题是作为可能的答案提供的。

正如答案的问题的建议,我代替intconst int和它的工作:

using Range =
  boost::any_range<
    int,
    boost::forward_traversal_tag,
    const int,
    std::ptrdiff_t>;

我决定发布这个问题,因为引用的问题没有标记为已回答。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM