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