-preview=in might break code

Mathias LANG geod24 at gmail.com
Fri Oct 2 21:13:29 UTC 2020


On Friday, 2 October 2020 at 14:08:29 UTC, Steven Schveighoffer 
wrote:
> Is there a way to prevent this?
>
> import std.stdio;
> struct S(size_t elems)
> {
>     int[elems] data;
> }
>
> void foo(T)(in T constdata, ref T normaldata)
> {
>     normaldata.data[0] = 1;
>     writeln(constdata.data[0]);
> }
> void main()
> {
>     S!1 smallval;
>     foo(smallval, smallval);
>     S!100 largeval;
>     foo(largeval, largeval);
> }
>
>
> Compile without -preview=in, it prints:
>
> 0
> 0
>
> Compile with -preview=in, it prints:
>
> 0
> 1
>
> -Steve

So what do we make of the following ?

```
import std.stdio;
struct S(size_t elems)
{
     int[elems] data;
     S copy () { return this; }
}

void foo(T)(auto ref T constdata, ref T normaldata)
{
     normaldata.data[0] = 1;
     writeln(constdata.data[0]);
}
void main()
{
     S!1 smallval;
     foo(smallval.copy, smallval);
     foo(smallval, smallval);
}
```

To me, the `in` approach is better. From the point of view of 
`foo`'s implementer, you get a stable `ref` or non-`ref` (not 
both!). You can also rely on it being `ref` if you know more 
about the type (e.g. if it has a destructor).
 From the point of view of the caller, calling the function with 
the same values will always behave the same, no matter if you 
pass rvalues or lvalues.


More information about the Digitalmars-d mailing list