www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Auto objects and scope

reply genie <sgenie maxnet.co.nz> writes:
Forgive my ignorance, guys, but there is something in GC for D I
can't spin my head about - look at this bit of code:

Test tst=new Test;

...
if(b)
{
   auto Test t1=new Test;
   ...
   tst=t1;
}
...
tst.func();

auto modifier forces the object to be deleted even though it was
assigned to something else before leaving the scope - is this
behaviour correct?

Gene
Nov 16 2006
next sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
genie wrote:
 Forgive my ignorance, guys, but there is something in GC for D I
 can't spin my head about - look at this bit of code:
 
 Test tst=new Test;
 
 ...
 if(b)
 {
    auto Test t1=new Test;
    ...
    tst=t1;
 }
 ...
 tst.func();
 
 auto modifier forces the object to be deleted even though it was
 assigned to something else before leaving the scope - is this
 behaviour correct?
 
 Gene

Yep. auto (now 'scope') is not a reference counter. It just says delete this one variable when this one variable goes out of scope. I think it's more or less equivalent to "scope(exit) delete t1;". In fact it will merrily delete whatever t1 happens to point to at the end of the scope: --------------------------- import std.stdio : writefln; class C { this(char[]n) { name=n; } ~this() { writefln("Bye bye: ", name); } char [] name; } void main() { auto a = new C("a"); { auto scope b = new C("b"); b=a; writefln("Leaving scope..."); } writefln("Left scope."); writefln("Ending main"); } /* Output: Leaving scope... Bye bye: a Left scope. Ending main Bye bye: b */ a gets deleted at the end of the scope instead of b, and b only gets cleaned up later by the final garbage collection sweep. So it seems it really is just syntactic sugar for the scope(exit) statement. I think some sort of reference-counting construct is needed for the type of cases your example illustrates. For things like File objects, you want to be able to return them, but you want them to be cleaned up immediately when no longer in use. 'scope' is too limited I think. I'm not sure how to do it though. It's not clear how to do in a clean way as a library (like a shared_ptr!()) without an overloadable opAssign. --bb
Nov 16 2006
next sibling parent genie <sgenie maxnet.co.nz> writes:
Thanks, Bill - that's the answer I was looking for. I assumed that
some kind of a reference counting was used in D for looking after the
state of the objects.

Gene
Nov 16 2006
prev sibling parent Boris Kolar <boris.kolar globera.com> writes:
== Quote from Bill Baxter (dnewsgroup billbaxter.com)'s article
 I think some sort of reference-counting construct is needed for the type
 of cases your example illustrates.  For things like File objects, you
 want to be able to return them, but you want them to be cleaned up
 immediately when no longer in use.  'scope' is too limited I think.
 I'm not sure how to do it though.  It's not clear how to do in a clean
 way as a library (like a shared_ptr!()) without an overloadable opAssign.
 --bb

I agree completely. Here is a different solution for a similar problem: http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=44163 Ideally, even cases like this should have deterministic finalization: void test() { getFile().read(buffer); // the File instance returned by getFile is destroyed here // (assuming it's not used outside this scope, of course) } The easiest way IMHO is intruduction of value classes (which are immutable) and using reference counting for deterministic finalization. Note that (immutable) value classes can never form cyclic references, so this technique would work well. Potentially, value classes offer additional benefits by providing better opportunities for compile-time optimization (multithreading, caching,...).
Nov 17 2006
prev sibling parent Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
genie wrote:
 Forgive my ignorance, guys, but there is something in GC for D I
 can't spin my head about - look at this bit of code:
 
 Test tst=new Test;
 
 ....
 if(b)
 {
    auto Test t1=new Test;
    ...
    tst=t1;
 }
 ....
 tst.func();
 
 auto modifier forces the object to be deleted even though it was
 assigned to something else before leaving the scope - is this
 behaviour correct?
 
 Gene

Bill gave you a pretty complete answer, but I just wanted to point out you could do this to prevent the deletion: # if (b) { # scope Test t1 = new Test; # // ... # tst = t1; # t1 = null; // <-- this will prevent the deletion! # } -- Chris Nicholson-Sauls
Nov 16 2006