Boost logo

Boost Users :

Subject: Re: [Boost-users] Reverse for loop with boost::adaptors::reverse crashes
From: Matei David (matei_at_[hidden])
Date: 2014-11-25 15:56:59


On Tue, 25 Nov 2014 13:55:15 -0500
Matei David <matei_at_[hidden]> wrote:

> On Tue, 25 Nov 2014 16:41:02 +0000
> Neil Groves <neil_at_[hidden]> wrote:
>
> > On 25 November 2014 at 16:11, Filip Konvička
> > <filip.konvicka_at_[hidden]> wrote:
> >
> > > Hi,
> > >
> > > I was trying to replace BOOST_REVERSE_FOREACH with the standard
> > > range-based for loop.
> > >
> > > #include <boost/range/adaptor/reversed.hpp>
> > > #include <boost/foreach.hpp>
> > > #include <vector>
> > > #include <iostream>
> > >
> > > std::vector<int> getv() {
> > > return std::vector<int>{1,2,3};
> > > }
> > >
> > > int main(int argc, char* argv[]) {
> > > // works fine:
> > > BOOST_REVERSE_FOREACH(int i, getv())
> > > std::cout << i << std::endl;
> > > // crashes:
> > > for(int i : boost::adaptors::reverse(getv()))
> > > std::cout << i << std::endl;
> > > return 0;
> > > }
> > >
> > > Maybe this is basic C++ I should understand; it looks like the
> > > temporary vector returned by getv() gets destroyed in the 2nd loop
> > > too soon. I was wondering whether the adaptor could warn me that
> > > I'm using it in a wrong way (the code looks so nice and compiles
> > > cleanly...).
> > >
> > >
> > Hi, I maintain the Boost.Range library and this issue is the most
> > frustrating one. I've been unable to come up with a solution that
> > does not unacceptably deteriorate performance in valid cases. I've
> > thrown the problem wide open to the list and a number of other
> > people and there haven't been any solutions that wouldn't ruin the
> > interface or performance. I can only apologise for failing to
> > address this. I've tried for many hours to find a solution, but
> > failed.
> >
> > Our hope is with Range V3 and the standardisation proposal from Eric
> > Niebler. He has defined the lifetime of new Iterables and Range
> > Concepts to avoid this problem. With a new interface we can fix the
> > problem.
> >
> > I'm still open to solutions for the V2 Boost.Range. I'd certainly
> > not like to be irrationally blocking progress. The current
> > recommendation is to take a temporary outside of the loop. This can
> > often be a const reference temporary to extend the lifetime
> > sufficiently.
>
> Hi,
>
> Is this related to the issue I reported here?
> https://svn.boost.org/trac/boost/ticket/10789

Looking more into this issue, I found this bug report from 2 years ago
that describes what I think is the underlying problem:
https://svn.boost.org/trac/boost/ticket/7630

Given that the issue (bug?) involves a use case as simple as the one
described by OP, many people might be bothered by it. Not everyone will
know to ask on this list. Worse still, some might invest time in
uselessly reporting the same issue all over again. For these reasons, I
strongly agree with OP in suggesting that a *big warning sign* should be
included in the Boost Range 2.0 documentation about this issue:

   "Thou shalt not use boost range adaptors on rvalue containers in
   C++11 range-based for loops."

If the note is already there, then it is not prominent enough.

Regarding solutions or workarounds, the last post by neilgroves in the
bug report is from 9 months ago, suggesting he has a solution. Are
there any updates on that?


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net