DIP 1016--ref T accepts r-values--Formal Assessment
Steven Schveighoffer
schveiguy at gmail.com
Thu Jan 31 16:38:42 UTC 2019
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
More information about the Digitalmars-d-announce
mailing list