[tiny] CWG 900 and 1498
Geoffrey Romer

Created on 2014-05-31.00:00:00 last changed 122 months ago


Date: 2014-07-01.21:57:43

The discussion thread started at [c++std-core-25298]

The core issues are CWG 900 and CWG 1498

Romer wrote:

The current resolutions of CWG 900 and 1498 don't seem right to me. The NAD rationale for CWG 900 appears to be saying that there is no problem, because the lifetime of _expression_ is extended by being bound to a reference. However, that applies only to the value of _expression_ itself; the lifetimes of any proper sub-expressions of _expression_ are not so extended. CWG 900 may be a little ambiguous about which temporaries it's referring to, but CWG 1498 is not; it's quite explicitly concerned with sub-expression temporaries, so the rationale for CWG 900 definitely does not apply.

To make this concrete, consider the following example, taken from https://svn.boost.org/trac/boost/ticket/7630:

 std::vector<int> vec;
 for (int val : vec | boost::adaptors::reversed
                    | boost::adaptors::uniqued) {
   // Do stuff with val

The behavior of this code is undefined, because the temporary returned by the subexpression (vec | boost::adaptors::reversed) is destroyed before the loop body is entered, leaving __range's referent holding a dangling reference to it. The adaptors can mostly fix the issue by overloading on rvalue references, but at the cost of a substantial increase in code complexity.

Smith suggested handling this as an EWG issue.

Discussed in Rapperswil 2014. EWG wants a solution, and welcomes a paper tackling the issue. Vandevoorde raised concerns introducing any new lifetime models. Stroustrup pointed out that the end-of-full-expression rule came about to reduce memory footprint compared to the end-of-block rule, and is good for RAII uses. Is it possible to solve the issue by just modifying the specification of a range-for loop?

Date User Action Args
2014-05-31 00:00:00admincreate