auto ref is on the docket
Jonathan M Davis via Digitalmars-d
digitalmars-d at puremagic.com
Fri Jun 26 18:18:17 PDT 2015
On Saturday, 27 June 2015 at 00:13:08 UTC, kinke wrote:
> On Thursday, 25 June 2015 at 10:10:42 UTC, Jonathan M Davis
> wrote:
>> Whether a reference escapes is an orthogonal issue. The return
>> attribute is for dealing with that. The function should be
>> able to return by ref or not and still accept both rvalues and
>> lvalues for its parameters. As long as the temporary variable
>> created for holding an rvalue exists for the duration of the
>> statement that the function call is in, it doesn't matter.
>
> When I was talking about escaping references, I didn't mean
> returned references; I meant storing a pointer to a ref
> parameter somewhere outside (global/instance variable).
That's a completely orthogonal issue to ref or auto ref. That's
an @system operation (since taking the address of a local
variable is @system), and it's up to you to not screw it up.
scope might cover that if it were fully ironed out, since that
does involve escaping, but it also might not, since it's an
@system operation and thus up to you not to screw it up.
Regardless, it has nothing to do with whether the function
accepts lvalues and rvalues with the same parameter. You have a
safety issue regardless if you're talking about taking a pointer
to an argument (or to some portion of the argument), since
there's no guarantee that the lifetime of the pointer is shorter
than that of the argument. That depends entirely on what the
argument was or what you do with the pointer, and very few
variables have a global lifetime, so whether the argument passed
to the ref parameter referred to a local variable is pretty much
irrelevant. You have to know what you're doing with you take the
address of a variable and make sure that you do it right.
Safety with regards to ref is an entirely different issue,
because that's @safe code. Also, whether the function might
return its ref parameter by ref is orthogonal to whether it
accepted an rvalue by ref or not, since whether you want to do
that or not doesn't necessarily have anything to with what's
being returned from the function (rather, it has to do with what
you want the function to accept), and you have a safety issue
even without having any kind of ref which accepts rvalues,
because all it requires is multiple layers of functions which
return by ref, and you're screwed anyway. e.g.
ref int id(ref int i)
{
return i;
}
ref int foo(ref int i)
{
++i;
return id(i);
}
ref int bar()
{
int i;
return foo(i);
}
We introduced the return attribute (currently only with -dip25)
to fix this problem. So, with that, we eliminate the safety
problem with ref itself, and we can safely have auto ref accept
rvalues by having it assign them to a temporary variable first.
The rules with returning by ref would then be the same with auto
ref as ref and require the return attribute to return a
parameter. And all of this is within @safe code.
Any issues with taking pointers to arguments is firmly in @system
territory and is thus completely orthogonal. Even if scope were
to be implemented in a way that prevented it, it would still have
nothing to do with whether the function accepted both rvalues and
lvalues with the same parameter.
> In the meantime, what about making all `ref` params accept
> rvalues
Please, please, no. ref indicates that your intention is to
mutate the argument. Having it accept rvalues completely destroys
that and makes it that much harder to understand what a function
is supposed to do. By having a separate attribute such as auto
ref which also accepts rvalues, we cleanly separate out the code
which just wants to accept both rvalues and lvalues for
efficiency purposes and the code that actually wants to take its
argument by ref so that it can mutate it.
- Jonathan M Davis
More information about the Digitalmars-d
mailing list