On Thursday, 31 January 2019 at 22:35:26 UTC, H. S. Teoh wrote:
On Thu, Jan 31, 2019 at 10:26:39PM +0000, jmh530 via Digitalmars-d-announce wrote:
On Thursday, 31 January 2019 at 21:57:21 UTC, Steven Schveighoffer wrote:
[...]
> That being said, you can look at the fact that most people > don't even know about this problem, even seasoned veterans, > as a sign that it's really not a big problem. >
The way you put it makes it sound like a bug...

I don't know if it helps, but below compiles without error.

struct Foo
{
   private int _x;
   int* x() { return &_x; }
}

struct Bar
{
   private Foo _y;
   Foo* y() { return &_y; }
   void y(Foo foo) { _y = foo; }
}

void main() {
    Foo a = Foo(1);
    assert(*a.x == 1);
    *a.x *= 2;
    assert(*a.x == 2);

    Bar b;
    b.y = Foo(1);
    assert(*b.y.x == 1);
    *b.y.x *= 2;
    assert(*b.y.x == 2);
}

Why is it a problem that this code compiles without error?


T

Sorry if I didn't really complete my thought.

The code below corresponds to the ref version mentioned above and gets the same error originally reported. The only difference is that I use Foo instead of Foo* for the getter in Bar. So if you instead make that member function a ref function, then it also compiles without error (regardless of if you use the doubleMyValue function or not).

So they were right that the issue is with the getter. However, you're not really protected in any way if you have a ref getter at one point in a chain and a non-ref getter somewhere else. Making all the getters auto ref also avoids the issue.

struct Foo
{
   private int _x;
   ref int x() { return _x; }
}

struct Bar
{
   private Foo _y;
   Foo y() { return _y; }
   void y(Foo foo) { _y = foo; }
}

void main() {
    Foo a = Foo(1);
    assert(a.x == 1);
    a.x *= 2;
    assert(a.x == 2);

    Bar b;
    b.y = Foo(1);
    assert(b.y.x == 1);
    b.y.x *= 2;
    assert(b.y.x == 2);
}

Reply via email to