On Thursday, 13 May 2021 at 19:48:44 UTC, Ali Çehreli wrote:
I was writing this example that shows a use case for the problem (marked with BUG below):
```D
struct Fraction {
    auto n = 0L;
    auto d = 1L;

    // ... other bits ...

    ref Fraction reduce() {
      import std.numeric : gcd;

      // v = gcd(n, d);
      // if (v > 1) {
      //   n /= v;
      //   d /= v;
      // }

      return this;
    }

    // ... etc ...
}

ref foo() {
  import std.stdio : writeln;
  auto f = Fraction(3, 9);

  // BUG: Returns reference to an object on the stack
  return f.reduce();
}

void main() {
  // Refers to a temporary (it would be a copy without the &)
  auto f = &foo();

// Do some unrelated things hoping that space for dead objects on
  // the stack will be reused.
  import std.stdio;
  import std.random;
  writeln("doing something else: ", uniform(0, 6));

writeln(f.d); // Access dead and overwritten object (does NOT print
                // 9 on my system)
}
```
Putting 'return' where Steve shows makes the compiler guard us against this misuse and the program thankfully does not compile.

Ali

Hi thank you both for your answers. I had understood from an earlier chapter how this could introduce a bug, but I was confused because the warning suggests attaching ```return``` to the parameter, which is empty in the declaration.

So my next question would be how come ref based operator overloads are not labelled as return and do not show this warning?

``` D
struct Fraction {
    auto n = 0L;
    auto d = 1L;

    ref Fraction opUnary(string op)()
    if (op == "++") {
        n += d;
        return this;
    }
}

ref Fraction foo() {
    auto f = Fraction(1, 3);

    // Same bug as with reduce
    return ++f;
}
```

Reply via email to