-preview=in might break code

Mathias LANG geod24 at gmail.com
Sat Oct 3 21:36:00 UTC 2020


On Saturday, 3 October 2020 at 18:36:57 UTC, Andrei Alexandrescu 
wrote:
> [...]
>
> A good point. I can tell for myself. First, binding to 
> reference vs. value is always reproducible the same regardless 
> of platform particulars. Granted, maintenance is liable to 
> introduce puzzlers but more of a first-order nature (change a 
> call, get different resuts) as opposed to a long-distance issue 
> (add a field to the object, suddenly unrelated code breaks - 
> not to mention changes in compiler heuristics). Second, the 
> keyword "ref" is in there, which is a clear giveaway the 
> implementation code needs to expect that.

This is missing the point: In an `auto ref` function, *the 
implementer of the function* not only cannot rely on the 
`ref`-ness of the parameter(s), but must plan for both, since 
it's almost a certainty that the function will be instantiated 
with both ref and non-ref. With `in`, only one state is possible 
at a time. For anything that isn't a POD, that `ref` state will 
be stable. So, while both `auto ref` and `in` need to plan for 
both `ref` state if they appear on a template parameter without 
constraint, `in` will always behave the same for non-POD type, 
while `auto ref` will not.

 From the caller's point of view, it's also simpler with `in`. The 
same function will always be called, regardless of the 
lvalue-ness of the arguments provided. Hence, slight change at 
the call site, or in the surrounding context, that could affect 
lvalue-ness, will not lead to a different function being called, 
as it would for `auto ref`.

A platform dependent change of lvalue-ness is trivial to craft 
using only `auto ref`:
```
void foo () (auto ref size_t value)
{
     pragma(msg, __traits(isRef, value));
}
auto ref size_t platform (uint* param) { return *param; }
extern(C) void main ()
{
     uint value;
     foo(platform(&value));
}
```

Tested on Linux64:
```
% dmd -betterC -run previn.d
false
% dmd -betterC -m32 -run previn.d
true
```


More information about the Digitalmars-d mailing list