Returning a reference to be manipulated

Dennis dkorpel at gmail.com
Fri Apr 14 11:18:21 UTC 2023


On Friday, 14 April 2023 at 10:31:58 UTC, kdevel wrote:
> But in fact it is returned unless it is `return ref`.

When using `return ref`, `return scope`, `scope` etc., you should 
be using the latest compiler and annotate functions you want 
checked with `@safe`. In previous versions, the compiler would 
often conflate `return ref` and `return scope`, and it was also 
inconsistent in whether it would do checks in `@safe`, `@system`, 
and even 'default/unannotated' functions.

Now, it is more consistent, performing checks in `@safe` code 
only.

> I don't get it! Is there any legitimate use of returning a ref 
> such that it outlives the matching argument's lifetime? If not: 
> Isn't this `return ref` completely redundant?

The annotation is needed because the compiler can't always figure 
out what you're doing with a `ref` parameter:

```D
ref int mysteryFunc(ref int x) @safe; // external implementation

ref int escape() @safe
{
     int local; // allocated on stack frame, should not escape 
this function
     return mysteryFunc(local); // is this safe?
}
```

Is this indeed `@safe`? It is, provided that `mysteryFunc` 
doesn't return its parameter `x`. It can be implemented like this 
for example:


```D
ref int mysteryFunc(ref int x) @safe
{
     x++;
     return *(new int);
}
```

But it wouldn't be safe if `x` were returned, so the compiler 
must know about that when it happens, hence `return ref`:
```D
ref int mysteryFunc(return ref int x) @safe
{
     return x;
}
```

Now the compiler can catch that `return mysteryFunc(local)` is 
unsafe. Note that if `mysteryFunc` is a template function, nested 
function, or returns `auto`, then the compiler infers attributes 
automatically, including `return ref`. Then you can still write 
it as `mysteryFunc(ref int x)` and it will automatically be 
treated as `return ref`.


More information about the Digitalmars-d-learn mailing list