auto ref is on the docket

Jonathan M Davis via Digitalmars-d digitalmars-d at puremagic.com
Mon Jun 29 10:19:46 PDT 2015


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


More information about the Digitalmars-d mailing list