| Thread overview | |||||||||
|---|---|---|---|---|---|---|---|---|---|
|
April 06, 2008 Extending "scope" | ||||
|---|---|---|---|---|
| ||||
I wrote something about "GC vs delete", but after thinking about it some more, how about this...
There seems to be a fundamental conflict between RAII and the garbage collector. You can assign a new object to a "scope" variable to cause it to get destructed without waiting for the GC, but what about objects within that? For example:
class tBar {
this()
{
writeln("a bar has been constructed");
}
~this()
{
writeln("a bar has been destructed");
}
}
class tFoo {
scope tBar bar;
this()
{
bar = new tBar();
writeln("a foo has been constructed");
}
~this()
{
delete bar;
writeln("a foo has been destructed");
}
}
unittest {
auto foo = new tFoo();
}
If you run this, you'll get:
a bar has been constructed
a foo has been constructed
At some point, you _may_ also get:
a bar has been destructed
a foo has been destructed
When it comes to RAII, that's not enough. Walter has allowed us to specify a class as being "scope" which requires you to create them with "scope auto foo = new tFoo()". However, if I also add that property to "tBar", it won't compile.
scope class tBar {
this()
{
writeln("a bar has been constructed");
}
~this()
{
writeln("a bar has been destructed");
}
}
scope class tFoo {
tBar bar;
this()
{
bar = new tBar();
writeln("a foo has been constructed");
}
~this()
{
delete bar;
writeln("a foo has been destructed");
}
}
unittest {
scope auto foo = new tFoo();
}
$ dmd ...
test.d(32): variable socket_test.tFoo.bar globals, statics, fields, manifest constants, ref and out parameters cannot be auto
test.d(32): variable socket_test.tFoo.bar reference to scope class must be scope
Nor can I declare a member variable "scope tBar bar" within class tFoo. In other words, it's not possible to embed one enforced RAII object within another.
What do others think about extending "scope" to allow it to be applied to member data? They would by default be set to "null" but have the requirement that they must be set exactly once in the constructor and nowhere else. They would also be deleted automatically during the destructor.
Or... Is there a different way to accomplish this?
-- Brian
| ||||
April 06, 2008 Re: Extending "scope" | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Brian White | On Sun, 06 Apr 2008 09:36:15 +0100, Brian White <bcwhite@pobox.com> wrote:
> I wrote something about "GC vs delete", but after thinking about it some more, how about this...
>
> There seems to be a fundamental conflict between RAII and the garbage collector. You can assign a new object to a "scope" variable to cause it to get destructed without waiting for the GC, but what about objects within that? For example:
>
You want a transitive delete. :)
| |||
April 06, 2008 Re: Extending "scope" | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Bruce Adams | "Bruce Adams" <tortoise_74@yeah.who.co.uk> wrote in message news:op.t86qykboxikks4@starquake.cybernetics... > On Sun, 06 Apr 2008 09:36:15 +0100, Brian White <bcwhite@pobox.com> wrote: > >> I wrote something about "GC vs delete", but after thinking about it some more, how about this... >> >> There seems to be a fundamental conflict between RAII and the garbage collector. You can assign a new object to a "scope" variable to cause it to get destructed without waiting for the GC, but what about objects within that? For example: >> > You want a transitive delete. :) Maybe it should be a paintable delete :P | |||
April 06, 2008 Re: Extending "scope" | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Brian White | "Brian White" <bcwhite@pobox.com> wrote in message news:fta21v$1ane$1@digitalmars.com... >I wrote something about "GC vs delete", but after thinking about it some more, how about this... > > There seems to be a fundamental conflict between RAII and the garbage collector. You can assign a new object to a "scope" variable to cause it to get destructed without waiting for the GC, but what about objects within that? For example: > > class tBar { > this() > { > writeln("a bar has been constructed"); > } > ~this() > { > writeln("a bar has been destructed"); > } > } > > class tFoo { > scope tBar bar; > > this() > { > bar = new tBar(); > writeln("a foo has been constructed"); > } > ~this() > { > delete bar; > writeln("a foo has been destructed"); > } > } > > unittest { > auto foo = new tFoo(); > } > > > If you run this, you'll get: > > a bar has been constructed > a foo has been constructed > > At some point, you _may_ also get: > > a bar has been destructed > a foo has been destructed > > > When it comes to RAII, that's not enough. Walter has allowed us to specify a class as being "scope" which requires you to create them with "scope auto foo = new tFoo()". However, if I also add that property to "tBar", it won't compile. > > scope class tBar { > this() > { > writeln("a bar has been constructed"); > } > ~this() > { > writeln("a bar has been destructed"); > } > } > > scope class tFoo { > tBar bar; > > this() > { > bar = new tBar(); > writeln("a foo has been constructed"); > } > ~this() > { > delete bar; > writeln("a foo has been destructed"); > } > } > > unittest { > scope auto foo = new tFoo(); > } > > $ dmd ... > test.d(32): variable socket_test.tFoo.bar globals, statics, fields, > manifest constants, ref and out parameters cannot be auto > test.d(32): variable socket_test.tFoo.bar reference to scope class must be > scope > > Nor can I declare a member variable "scope tBar bar" within class tFoo. In other words, it's not possible to embed one enforced RAII object within another. > > > What do others think about extending "scope" to allow it to be applied to member data? They would by default be set to "null" but have the requirement that they must be set exactly once in the constructor and nowhere else. They would also be deleted automatically during the destructor. > > Or... Is there a different way to accomplish this? > > -- Brian I think you're the 318th person to suggest this. I might be talking out of you-know-where but I think I remember Walter mentioning that this is in the cards for D2. | |||
April 06, 2008 Re: Extending "scope" | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Bruce Adams | Bruce Adams:
> You want a transitive delete. :)
And it sounds like an interesting feature.
Bye,
bearophile
| |||
April 06, 2008 Re: Extending "scope" | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | >> What do others think about extending "scope" to allow it to be applied to member data? They would by default be set to "null" but have the requirement that they must be set exactly once in the constructor and nowhere else. They would also be deleted automatically during the destructor.
>
> I think you're the 318th person to suggest this. I might be talking out of you-know-where but I think I remember Walter mentioning that this is in the cards for D2.
Well... I'm fairly new here. :-)
If it's in the cards for D2, it's not currently implemented there since that's the compiler I'm using.
I forgot to mention that of course only scope classes could have scope members, but I think that's fairly obvious.
-- Brian
| |||
April 09, 2008 Re: Extending "scope" | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Brian White | 在 Sun, 06 Apr 2008 16:36:15 +0800,Brian White <bcwhite@pobox.com> 写道:
I posted an enhancement bug for this particular issue. don't remember the bugid.
I suggest the scope class member as a local initialized stuff that's a struct like stuff.
--
使用 Opera 革命性的电子邮件客户程序: http://www.opera.com/mail/
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply