Binding rvalues to ref parameters redux

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Fri Mar 29 12:16:40 UTC 2019


On 3/29/19 7:32 AM, Olivier FAURE wrote:
> On Wednesday, 27 March 2019 at 01:38:40 UTC, Andrei Alexandrescu wrote:
>> https://gist.github.com/andralex/e5405a5d773f07f73196c05f8339435a
>>
>> Thanks in advance for any feedback.
> 
> - During discussions around DIP-1016, it was pointed out that the 
> following code currently compiles, even though it really shouldn't:
> 
>      struct Point
>      {
>          private int _x, _y;
>          ref int x() { return _x; }
>          ref int y() { return _y; }
>      }
> 
>      struct Rect
>      {
>          private Point _origin, _size;
>          Point origin() { return _origin; }
>          Point size() { return _size; }
>          void origin(Point p) { _origin = p; }
>          void size(Point p) { _size = p; }
>      }
> 
>      Rect r;
>      r.origin = Point(1, 2);
>      r.size = Point(5, 5);
>      doubleMyValue(r.size.x);
>      assert(r.lengths.x == 10); // fail
> 
> How would your proposal affect the above code?

That code would still compile because the draft DIP does not require a 
DotExpression a.b.c to have lvalues at all levels (i.e. all of a, b, and 
c); as long as c is a ref, a and b don't matter.

This is hardly a problem with the DIP though because this compiles and 
runs with the same uselessness:

r.size.x *= 2;

I could change the DIP to require lvalues throughout. Also, we should 
probably change the language to disallow other constructs as well. 
Essentially I think a.b.c should be an rvalue (even if it's ostensibly 
an lvalue) if any of a, b, or c is an rvalue.

> Either way, the proposal should probably include a description of how 
> the `this` reference of struct methods currently interacts with rvalues, 
> and how it will be affected by the proposal.

I have moved that part straight into the specification of lvalues and 
rvalues. "this" in struct and union types is an lvalue. In classes it's 
an rvalue.

> - Other corner cases that were raised during discussion of DIP-1016: 
> alias this, return ref, auto ref, and refs in foreach. The proposal 
> needs to address those.
> 
> - return ref in particular is interesting. How do you handle the 
> following code?
> 
>      int getGraphSize(ref Node);
>      Node makeNode(int x);
>      Node makeNode(return ref Node child1, return ref Node child2);
> 
>      // Probably should compile
>      getGraphSize(makeNode(makeNode(1), makeNode(2)));
> 
>      // Probably should not
>      auto persistentNode = makeNode(makeNode(1), makeNode(2));
>      // Invalid write
>      persitentNode.child1.x = 123;

Did you mean makeNode to return by reference?

Good list, thanks!


Andrei


More information about the Digitalmars-d mailing list