Rvalue references - The resolution

Steven Schveighoffer schveiguy at yahoo.com
Mon May 6 09:17:32 PDT 2013


On Mon, 06 May 2013 12:03:27 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail at erdani.org> wrote:

> On 5/6/13 11:48 AM, Steven Schveighoffer wrote:
>> On Mon, 06 May 2013 11:31:05 -0400, Andrei Alexandrescu
>> <SeeWebsiteForEmail at erdani.org> wrote:
>>> Consider the body of min isn't known (eliminate templates etc). Then
>>> what the compiler sees is a function call that returns a const ref.
>>> All it can assume is it's a valid reference which it will subsequently
>>> bind to the name given by the caller. The reference will refer
>>> therefore to a destroyed rvalue (temporaries are destroyed at the end
>>> of the full expression).
>>
>> Well, given that we intend to infer some special behavior given the
>> types of the parameters, I wouldn't think it was impossible to do the
>> same here. This would make the rvalue live beyond the expression, so
>> maybe that's not allowed in C++.
>
> I'm not sure I understand what you're suggesting.

Not suggesting anything.  I was inferring that since the code worked,  
maybe the compiler was correctly handling it.  And given that we plan to  
have special rules regarding ref, it's not out of the question C++ might  
also.

>
>>> Your example is irrelevant to this discussion because returning an
>>> rvalue and subsequently binding it to a const T& is a completely
>>> different scenario.
>>
>> I quote from your original rebuttal:
>>
>>> ref int min(ref int a, ref int b) { return b < a ? b : a; }
>>> ...
>>> int x;
>>> fun(min(x, 100));
>>
>> Which is returning an rvalue ref and subsequently binding it to a ref
>> parameter of fun.
>>
>> Isn't that the same thing?
>
> No. It's a very different thing handled by a special rule in C++.

This isn't helping.  You keep saying its different but not how.  I repeat,  
isn't it possible to solve the problem of binding rvalues to references?   
Yours and my examples seem to say it works in C++, but yet you say it's  
not feasible in D.  Why is C++ able to handle this while D is not?

>>> It would be also sound if it weren't for this:
>>>
>>> struct A {
>>> A(const T& x) : a(x) {}
>>> const T& a;
>>> };
>>>
>>> In _this_ case, initializing A with an rvalue of type T compiles and
>>> subsequently runs with undefined behavior.
>>
>> This seems like a separate ref problem. But we don't have ref members,
>> so it would require an address-of in D. That should be forbidden, right?
>
> Yes. My point was to illustrate that a special rule that works in a  
> situation can't help another.

Another situation that's already solved?  Don't see the point.

>> If you are saying we haven't solved the escape problem, that is news to
>> me. I thought the runtime check solves that.
>
> It does. But binding rvalues to ref makes bounds check failures more  
> frequent, less predictable, and harder to debug. Failures will be more  
> frequent because there's more chance that a ref refers to a defunct  
> rvalue;

That is a lifetime issue.  We can make the lifetime last long enough for  
the current statement.

> less predictable because conditional execution may cause some paths to  
> be rarely exercised;

An existing problem, not made worse by rvalue references.

> and harder to debug because rvalues come and go following implicit  
> rules, not visible scopes.

What are the rules?  Maybe we should start there.

-Steve


More information about the Digitalmars-d mailing list