Subject: [boost] Range Adapters (map_keys, map_values) cause undefined behavior (segv, etc) when applied to R-Values, especially in the context of BOOST_FOREACH
From: Igor Lubashev (igorlord_at_[hidden])
Date: 2014-01-29 15:43:47
I've filed a ticket (https://svn.boost.org/trac/boost/ticket/9578) for this issue two weeks ago, but I see no action there. Does anyone else think that this (see subj) is a problem?
To spare the trouble of following the link, here is the essence of the problem, as I see it. (The ticket has a simple test case attached.)
When applied to r-values (for example, maps returned by value from a function), adapters do not make a copy of the r-value but just capture a reference to it. This makes the returned range_iterator dangerous, if it is used after the r-value (the temporary) is destroyed.
In particular, the following use causes undefined behavior on all compilers I'd tested on: g++ (4.1.2, 4.4.3, 4.6.3) and Visual Studio (15 [VC9], 16 [VC10]).
BOOST_FOREACH(const string &s, return_map_by_value() | map_keys) ...
Note that the following works fine (since BOOST_FOREACH takes care of differentiating between l-values and r-values and does the right thing to r-values):
BOOST_FOREACH(const MapType::value_type &v, return_map_by_value()) ...
It seems that boost::range::adapters need to do a similar thing to what BOOST_FOREACH is does to identify r-values and make a copy (which the compiler is likely to optimize away).
Any comments are welcome!
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk