Title
[tiny] CWG 900 and 1498
Status
open
Section
[class.temporary]
Submitter
Geoffrey Romer

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

Messages

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?

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