Re: ref struct member function

2021-05-14 Thread Paul Backus via Digitalmars-d-learn

On Friday, 14 May 2021 at 10:00:28 UTC, PinDPlugga wrote:


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.


The error message here is definitely not as good as it could be.

As a general rule, if you want to apply an attribute to the 
`this` reference in a member function, you write it after the 
parameter list:


struct S
{
// ...

auto memberFunc() const scope
{
// `this` is const and scope
}

auto anotherOne() share inout
{
// `this` is shared and inout
}
}


Re: ref struct member function

2021-05-14 Thread ag0aep6g via Digitalmars-d-learn

On 14.05.21 12:00, PinDPlugga wrote:
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.


`this` is considered a hidden parameter. Every non-static method has it.

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;
}
```


Note that opUnary is not an ordinary method. It's a template. That means 
attributes are inferred [1], including the `return` attribute. I.e., the 
compiler adds `return` to the signature for you, just like Steven 
suggested you do manually.


Try omitting the return type of `reduce` in your original code:

 ref reduce() { ... }

That also enables attribute inference, and your code will compile.


[1] https://dlang.org/spec/function.html#function-attribute-inference


Re: ref struct member function

2021-05-14 Thread PinDPlugga via Digitalmars-d-learn

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 = ();

  // 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;
}
```


Re: ref struct member function

2021-05-13 Thread Ali Çehreli via Digitalmars-d-learn

On 5/13/21 12:40 PM, Steven Schveighoffer wrote:

On 5/13/21 3:21 PM, PinDPlugga wrote:


This works but issues a deprecation warning:
```
onlineapp.d(30): Deprecation: returning `this` escapes a reference to 
parameter `this`

onlineapp.d(30):    perhaps annotate the parameter with `return`
Fraction(1, 3)
```

I found several other ways to make this work without the warnings, but 
I am wondering how to make this particular case work, or if it is not 
a recommended way, what the proper way would be.


Just follow the recommendation:

```d
ref Fraction reduce() return { // annotated with return
```

This means, "I will return all or part of the parameter passed in" (the 
parameter being the `this` reference)


-Steve


I was writing this example that shows a use case for the problem (marked 
with BUG below):


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 = ();

  // 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



Re: ref struct member function

2021-05-13 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/13/21 3:21 PM, PinDPlugga wrote:


This works but issues a deprecation warning:
```
onlineapp.d(30): Deprecation: returning `this` escapes a reference to 
parameter `this`

onlineapp.d(30):    perhaps annotate the parameter with `return`
Fraction(1, 3)
```

I found several other ways to make this work without the warnings, but I 
am wondering how to make this particular case work, or if it is not a 
recommended way, what the proper way would be.


Just follow the recommendation:

```d
ref Fraction reduce() return { // annotated with return
```

This means, "I will return all or part of the parameter passed in" (the 
parameter being the `this` reference)


-Steve


ref struct member function

2021-05-13 Thread PinDPlugga via Digitalmars-d-learn
Hi I am working through Programming in D. In one exercise I have 
a helper function in a struct


```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 ...
}

void main() {
  import std.stdio : writeln;
  auto f = Fraction(3, 9);
  writeln(f.reduce());
}
```

This works but issues a deprecation warning:
```
onlineapp.d(30): Deprecation: returning `this` escapes a 
reference to parameter `this`
onlineapp.d(30):perhaps annotate the parameter with 
`return`

Fraction(1, 3)
```

I found several other ways to make this work without the 
warnings, but I am wondering how to make this particular case 
work, or if it is not a recommended way, what the proper way 
would be.