On Monday, 7 August 2017 at 13:40:18 UTC, Moritz Maxeiner wrote:
Thanks, I wasn't aware of this. I tried fooling around scope
classes and DIP1000 for a bit and was surprised that this is
allowed:
---
import core.stdc.stdio : printf;
import std.algorithm : move;
class A
{
int i;
this() @safe
{
i = 0;
}
}
void inc(scope A a) @safe
{
a.i += 1;
}
void print(scope A a) @trusted
{
printf("A@%x: %d\n", cast(void*) a, a.i);
}
auto makeA() @safe
{
scope a = new A();
a.print();
return move(a);
}
void main() @safe
{
auto a = makeA();
foreach (i; 0..10) {
a.print();
a.inc();
}
}
---
You can still create a (scope) class on the stack, escape a
reference to it using `move` and use it afterwards, all within
the rules of @safe, so I'm not convinced that the reason for
deprecating scoped classes is gone yet.
Compare this to `scoped`, which behaves as expected (since it
wraps the reference type object in a value type):
---
import std.typecons : scoped;
auto makeA() @trusted
{
auto a = scoped!A();
a.print();
return move(a);
}
void main() @trusted
{
auto a = makeA();
foreach (i; 0..10) {
a.print();
a.inc();
}
}
---
Forgot to add the runtime output after compiling with `dmd a.d
-dip1000`:
For `scope A`:
A@198d1568: 0
A@198d1568: 0
A@198d1568: 1
A@198d1568: 2
A@198d1568: 3
A@198d1568: 4
A@198d1568: 5
A@198d1568: 6
A@198d1568: 7
A@198d1568: 8
A@198d1568: 9
For `scoped!A`:
A@8de538b8: 0
A@8de53940: 0
A@8de53940: 1
A@8de53940: 2
A@8de53940: 3
A@8de53940: 4
A@8de53940: 5
A@8de53940: 6
A@8de53940: 7
A@8de53940: 8
A@8de53940: 9