Bug 10921 – scoped returns a reference to an uninitialized object
Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-08-29T06:58:59Z
Last change time
2019-11-18T15:39:44Z
Assigned to
No Owner
Creator
Andrej Mitrovic
Comments
Comment #0 by andrej.mitrovich — 2013-08-29T06:58:59Z
-----
import std.conv;
import std.typecons;
class Point
{
this(int x, int y)
{
this.x = x;
this.y = y;
}
int x;
int y;
}
void main()
{
auto p1 = scoped!Point(1, 2);
assert(p1.x == 1, p1.x.text); // ok
assert(p1.y == 2, p1.y.text); // ok
Point p2 = scoped!Point(1, 2);
assert(p2.x == 1, p2.x.text); // fails, == 0
assert(p2.y == 2, p2.y.text); // fails, == 0
}
-----
Comment #1 by andrej.mitrovich — 2013-08-29T07:01:00Z
Note however that it only fails when declaring, not when assigning. The following works properly:
-----
import std.conv;
import std.typecons;
class Point
{
this(int x, int y)
{
this.x = x;
this.y = y;
}
int x;
int y;
}
void main()
{
auto p1 = scoped!Point(1, 2);
assert(p1.x == 1, p1.x.text); // ok
assert(p1.y == 2, p1.y.text); // ok
Point p2 = p1;
assert(p2.x == 1, p2.x.text); // ok
assert(p2.y == 2, p2.y.text); // ok
}
-----
Comment #2 by andrej.mitrovich — 2013-08-29T07:04:28Z
(In reply to comment #0)
> -----
> Point p2 = scoped!Point(1, 2);
> assert(p2.x == 1, p2.x.text); // fails, == 0
> assert(p2.y == 2, p2.y.text); // fails, == 0
> }
> -----
I see now what's going on, the internal voldemort type `static struct Scoped` has a dtor, and it is called because this struct is thrown away when you just want to assign the reference to the object at the call site.
So the bug report itself is invalid, however this should really be documented because it's very hard to spot what went wrong.
Comment #3 by k.hara.pg — 2013-08-29T18:38:53Z
(In reply to comment #2)
> (In reply to comment #0)
> > -----
> > Point p2 = scoped!Point(1, 2);
> > assert(p2.x == 1, p2.x.text); // fails, == 0
> > assert(p2.y == 2, p2.y.text); // fails, == 0
> > }
> > -----
>
> I see now what's going on, the internal voldemort type `static struct Scoped`
> has a dtor, and it is called because this struct is thrown away when you just
> want to assign the reference to the object at the call site.
>
> So the bug report itself is invalid, however this should really be documented
> because it's very hard to spot what went wrong.
We should disable the implicit conversion from Scoped to Point.
I think we can use Proxy mixin instead of alias this for the purpose.
Comment #4 by andrej.mitrovich — 2013-08-30T06:42:16Z
(In reply to comment #3)
> We should disable the implicit conversion from Scoped to Point.
Maybe.. but I have a feeling this would break code. E.g.:
void callback(scoped Event event) { }
auto event = scoped!Event(...);
callback(event); // implicit, but OK
Now if the 'scope' storage class actually did something useful in a parameter list, then the above would also be safe.
I suppose you want this to become:
callback(cast(Event)event);
I could live with that, but I'm not sure if any code for other people would break. I hear relatively little about people using scoped (most people seem to use emplace instead).
Comment #5 by bugzilla — 2019-11-18T15:39:44Z
Meanwhile this has been addressed by adding an explaining example in the unittest.