On Mon, 06 May 2013 12:03:27 -0400, Andrei Alexandrescu <[email protected]> wrote:

On 5/6/13 11:48 AM, Steven Schveighoffer wrote:
On Mon, 06 May 2013 11:31:05 -0400, Andrei Alexandrescu
<[email protected]> 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

Reply via email to