ref struct member function
Ali Çehreli
acehreli at yahoo.com
Thu May 13 19:48:44 UTC 2021
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 = &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
More information about the Digitalmars-d-learn
mailing list