On Sunday, 28 June 2015 at 10:50:10 UTC, Marc Schütz wrote:
Thank you Jonathan, I think I (like kinke in his post above) finally understand your stance. So I guess from your POV the following would be an ideal situation (disregarding the need to avoid breaking changes):

1) `auto ref` for non-templates is required to make a function accept rvalue and lvalue refs alike. 2) `auto ref` for templates is changed to mean the same thing as 1).
3) `scope ref` prevents escaping of the reference.

Neither of `auto ref` and `scope ref` would imply the other, because you want to treat them as orthogonal. Do I understand you right?

The main problems with this is that they aren't in fact orthogonal: `auto ref` without `scope ref` almost only makes sense if you want to deliberately break something. Furthermore, `auto ref` is already taken for something else, and I'm not sure Walter would be too happy if we wanted to change its meaning for templates.

We definitely don't want to lose the current auto ref that we have with templates. It's critical for forwarding refness, even if we got that ability by accident. IIRC, we don't quite manage perfect forwarding with what we have (though off the top of my head, I don't recall what we're missing), but without auto ref, we definitely don't get there. So, auto ref, as it stands has proven to be surprisingly useful completely aside from efficiency concerns. Also, the fact that it takes rvalues by value can actually be more efficient than taking them by ref, depending on the code, since it can just move the value in that case, whereas it's tied to a temporary variable in the case of what would be the non-templated auto ref, and that could require copying the value at some point when having it be passed by value could have avoided the copy - though obviously, all of that template bloat comes at a cost, so it's definitely a tradeoff. But we don't want to lose the current auto ref regardless.

So, if we want to have an attribute which accepts both lvalues and rvalues for non-templated functions and be able to use that same attribute for templated functions, a new attribute is required (even if originally, auto ref was intended to work for both templated and non-templated functions). Otherwise, if we're fine with the template bloat, we can just use the proposed auto ref with non-templated functions and not worry about adding a new attribute. So, ideally, at this point, we'd probably add a new attribute, simply because it's the most flexible, but that does come at the cost of adding a new attribute, so it may not be worth it.

Regardless, all of that is orthogonal to the escaping issue, because the escaping issue exists for all ref variables (not just those which refer to temporary variables that rvalues were assigned to). So, whether a ref parameter accepts both lvalues and rvalues is separate from whether they escape. And if scope really prevented the ref from escaping, then you couldn't even return it, and we need to be able to return by ref, so scope ref really doesn't make sense in the context of preventing ref parameters from existing longer than their arguments. It's related, but it would be too restrictive if it truly prevented all escaping.

And as far as escaping references to ref parameters by returning them by ref goes, the recently added return attribute already takes care of that. So, arguably, it overlaps with what scope conceivably could or should do, but it does what's required for solving the escape problem for ref, and a more general scope solution is not required for that. It also allows us to distinguish between ensuring that a ref parameter does not exist longer than is safe (i.e. that it's only returned by ref if it's safe to do so) and preventing a ref parameter from escaping the function at all. So, if we were to ever add scope ref, then presumably that would have to do with other types of escaping than simply returning by ref. And whether you wanted to prevent a ref parameter from escaping - either by being returned by ref or by other means - isn't necessarily related to whether it refers to a temporary variable that was an rvalue, much as it's clearly more dangerous to escape anything which refers to a ref parameters if it refers to a temporary variable that won't last beyond the statement that the function was called in.

- Jonathan M Davis

Reply via email to