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