# DIP 1016--ref T accepts r-values--Formal Assessment

Andrei Alexandrescu SeeWebsiteForEmail at erdani.com
Thu Jan 31 21:28:25 UTC 2019

```On 1/31/19 11:38 AM, Steven Schveighoffer wrote:
> On 1/31/19 11:04 AM, Olivier FAURE wrote:
>> On Thursday, 31 January 2019 at 02:10:05 UTC, Manu wrote:
>>> I still can't see a truck-sized hole.
>>
>> I don't know if it's truck-sized, but here's another corner case:
>>
>>      int doubleMyValue(ref int x) {
>>          x *= 2;
>>          return x;
>>      }
>>
>>      Point pt;
>>      pt.x = 5;
>>      pt.y = foobar();
>>
>>      doubleMyValue(pt.x);
>>      assert(pt.x == 10);
>>
>> Question: in the above code, will the assertion pass?
>>
>> Answer: it depends on Point's implementation. If x is a member
>> variable, then yes. If it's a getter, then doubleMyValue will take a
>> rvalue and x won't be mutated and the assertion will fail.
>>
>> I think this is a non-trivial conceptual problem.
>
> Yeah, that's already a thing that ref in D doesn't protect against:
>
> struct Point
> {
>     private int _x, _y;
>     ref int x() { return _x; }
>     ref int y() { return _y; }
> }
>
> struct Rect
> {
>     private Point _origin, _lengths;
>     Point origin() { return _origin; }
>     Point lengths() { return _lengths; }
>     void origin(Point p) { _origin = p; }
>     void lengths(Point p) { _lengths = p; }
> }
>
> Rect r;
> r.origin = Point(1, 2);
> r.lengths = Point(5, 5);
> doubleMyValue(r.lengths.x);
> assert(r.lengths.x == 10); // fail
>
> -Steve

Affirmative. This discussion should be part of the revised DIP along
with an assessment of its gravity.

Goes the same with scope-level variables replaced with homonym functions
that return rvalues.

Andrei
```