Jump to page: 1 2 3
Thread overview
Questions about new() and auto classes
May 09, 2005
Oliver
May 09, 2005
Andrew Fedoniouk
May 10, 2005
Derek Parnell
May 10, 2005
Ben Hinkle
May 10, 2005
Burton Radons
May 10, 2005
Sean Kelly
May 10, 2005
Burton Radons
May 12, 2005
Kevin Bealer
May 10, 2005
Ben Hinkle
May 10, 2005
Ben Hinkle
May 10, 2005
Sean Kelly
May 10, 2005
Mike Capp
May 11, 2005
Kevin Bealer
May 11, 2005
Kevin Bealer
May 11, 2005
Andrew Fedoniouk
May 11, 2005
Mike Capp
May 13, 2005
B.G.
May 13, 2005
Ben Hinkle
May 13, 2005
B.G.
May 13, 2005
Ben Hinkle
May 09, 2005
Hello !

I am new to D and have a bit of experience with C++.
The D manual says the folowing :

Instances of class objects are created with NewExpressions:

A a = new A(3);

Then there is a detailed explanation of what happens when new() is used. In the same chapter there is an explanation about auto classes :

When an auto class reference goes out of scope, the destructor (if any) for it is automatically called. This holds true even if the scope was exited via a thrown exception.

My questions :

1.Does that mean that the destructor is not called for a non-auto class that goes out of scope and for which no references are left ?

2.Is new() the only way to create new instances of classes ?
(or writing your own new)

3.When an object that has been allocated with new() has only one reference and this reference goes out of scope, is the object automatically deleted by the GC ?

Help would be appreciated.

Regards, Oliver


May 09, 2005
> When an auto class reference goes out of scope, the destructor (if any)
> for it
> is automatically called. This holds true even if the scope was exited via
> a
> thrown exception.
>
> My questions :
>
> 1.Does that mean that the destructor is not called for a non-auto class
> that
> goes out of scope and for which no references are left ?

Yes, destructor is not called immediately in this case.
GC will call delete of your object later - when it will collect garbage.

>
> 2.Is new() the only way to create new instances of classes ?
> (or writing your own new)

Yes.
But remeber that instances of structures behave differently and
you can allocate them on stack.
In D class and structure are not synonyms. (which is good, IMHO)

>
> 3.When an object that has been allocated with new() has only one reference
> and
> this reference goes out of scope, is the object automatically deleted by
> the GC
> ?

Automatic deletion happens during garbage collection which might not occur at all.

> Help would be appreciated.

BTW: There is a digitalmars.d.learn newsgroup. I think that you may find some useful answers there.

Regards.

Andrew.


May 10, 2005
"Oliver" <Oliver_member@pathlink.com> wrote in message news:d5oaah$189q$1@digitaldaemon.com...
> 1.Does that mean that the destructor is not called for a non-auto class
> that
> goes out of scope and for which no references are left ?
> 3.When an object that has been allocated with new() has only one reference
> and
> this reference goes out of scope, is the object automatically deleted by
> the GC
> ?

With regards to these two questions: As Andrew noted in his reply, the destructors will be called when the GC is run.

Usually.

If the GC is run during the program, it will call the destructor on any class instances which need it.

However, at the end of the program, all allocated memory is deleted - but no destructors are called.

This is, in my opinion, inconsistent and very bad behavior.  This model assumes that D programs will only perform vanilla memory allocation, and that they will not create other kinds of resources (COM objects, video card resources, etc.) which are _not_ handled by the program itself and which must be cleaned up manually.

I really hope this behavior changes.


May 10, 2005
On Mon, 9 May 2005 20:25:00 -0400, Jarrett Billingsley wrote:

> "Oliver" <Oliver_member@pathlink.com> wrote in message news:d5oaah$189q$1@digitaldaemon.com...
>> 1.Does that mean that the destructor is not called for a non-auto class
>> that
>> goes out of scope and for which no references are left ?
>> 3.When an object that has been allocated with new() has only one reference
>> and
>> this reference goes out of scope, is the object automatically deleted by
>> the GC
>> ?
> 
> With regards to these two questions: As Andrew noted in his reply, the destructors will be called when the GC is run.
> 
> Usually.
> 
> If the GC is run during the program, it will call the destructor on any class instances which need it.
> 
> However, at the end of the program, all allocated memory is deleted - but no destructors are called.

What?!?! That's crazy! That's like saying that D regards RAM as the only resource that we have to manage.

> This is, in my opinion, inconsistent and very bad behavior.  This model assumes that D programs will only perform vanilla memory allocation, and that they will not create other kinds of resources (COM objects, video card resources, etc.) which are _not_ handled by the program itself and which must be cleaned up manually.
> 
> I really hope this behavior changes.

Absolutely. I'd be worried about databases and file locks too. Not all files are locked using the operating system's built-in mechanism.

-- 
Derek
Melbourne, Australia
10/05/2005 10:41:23 AM
May 10, 2005
"Jarrett Billingsley" <kb3ctd2@yahoo.com> wrote in message news:d5ouoi$2i8$1@digitaldaemon.com...
> "Oliver" <Oliver_member@pathlink.com> wrote in message news:d5oaah$189q$1@digitaldaemon.com...
>> 1.Does that mean that the destructor is not called for a non-auto class
>> that
>> goes out of scope and for which no references are left ?
>> 3.When an object that has been allocated with new() has only one
>> reference and
>> this reference goes out of scope, is the object automatically deleted by
>> the GC
>> ?
>
> With regards to these two questions: As Andrew noted in his reply, the destructors will be called when the GC is run.
>
> Usually.
>
> If the GC is run during the program, it will call the destructor on any class instances which need it.
>
> However, at the end of the program, all allocated memory is deleted - but no destructors are called.

Current the GC is run at program exit. Many of us wish it weren't. To me the
three main reasons why it shouldn't run is
1) it is run after the module dtors which means your destructors can't rely
on anything that depends on the module being "initialized"
2) it sucks up significant time to quit when the OS will reclaim
"everything" anyway (people may disagree on what "everything" means)
3) dtors aren't guaranteed to run anyway so in particular people can't count
on them to run at program exit.

> This is, in my opinion, inconsistent and very bad behavior.  This model assumes that D programs will only perform vanilla memory allocation, and that they will not create other kinds of resources (COM objects, video card resources, etc.) which are _not_ handled by the program itself and which must be cleaned up manually.
>
> I really hope this behavior changes.

Note any resource that is only freed by a destructor is a leak independent of the exit behavior since the dtor might not be run ever.


May 10, 2005
"Ben Hinkle" <ben.hinkle@gmail.com> wrote in message news:d5p0gn$3k0$1@digitaldaemon.com...
> Current the GC is run at program exit. Many of us wish it weren't. To me
> the three main reasons why it shouldn't run is
> 1) it is run after the module dtors which means your destructors can't
> rely on anything that depends on the module being "initialized"
> 2) it sucks up significant time to quit when the OS will reclaim
> "everything" anyway (people may disagree on what "everything" means)
> 3) dtors aren't guaranteed to run anyway so in particular people can't
> count on them to run at program exit.

Well, what I'm suggesting is that the spec *change* so that dtors _are_ guaranteed to be run.  I find that to be rather important behavior.

Besides - if your program is taking a long time to exit when the GC is run at the end, that just sounds like a case of extremely lax memory management programming.  Now yes, the GC is supposed to clean up after us if we make mistakes and to make some things easier - but it's just irresponsible to _never_ delete anything that you're done with!

> Note any resource that is only freed by a destructor is a leak independent of the exit behavior since the dtor might not be run ever.

So.. when else are we supposed to release these other resources?  The dtor seems like a rather logical place to do this, especially if these resources are created in the ctor..


May 10, 2005
Jarrett Billingsley wrote:

> "Ben Hinkle" <ben.hinkle@gmail.com> wrote in message news:d5p0gn$3k0$1@digitaldaemon.com...
> 
>>Current the GC is run at program exit. Many of us wish it weren't. To me the three main reasons why it shouldn't run is
>>1) it is run after the module dtors which means your destructors can't rely on anything that depends on the module being "initialized"
>>2) it sucks up significant time to quit when the OS will reclaim "everything" anyway (people may disagree on what "everything" means)
>>3) dtors aren't guaranteed to run anyway so in particular people can't count on them to run at program exit.
> 
> 
> Well, what I'm suggesting is that the spec *change* so that dtors _are_ guaranteed to be run.  I find that to be rather important behavior.
> 
> Besides - if your program is taking a long time to exit when the GC is run at the end, that just sounds like a case of extremely lax memory management programming.  Now yes, the GC is supposed to clean up after us if we make mistakes and to make some things easier - but it's just irresponsible to _never_ delete anything that you're done with!

Okay, both sides of the debate here are confused as to what is currently going on in the GC.  Here's an example to illustrate it:

    class C
    {
        char [] name;

        this (char [] name)
        {
            this.name = name;
        }

        ~this ()
        {
            printf ("DELETED %.*s!\n", name);
        }
    }

    C global;

    void main ()
    {
        C stack = new C ("Stack");
        new C ("Heap");
        global = new C ("Global");
    }

When run, this prints "DELETED Stack!" and "DELETED Heap!", leaving the global undeleted.  That's because the GC DOES try to clean up after itself but calls the wrong function - instead of calling collectNoStack (which still scans static data), it should call a function that does nothing but call destructors in all the allocated objects, which would be a very fast pass.

If this were fixed and a replacement for gc.d/gcx.d were sent to Walter, I see no reason why he wouldn't include it in Phobos.

There's another deficiency in that signals are not handled, so if you replace the main with this:

    void main ()
    {
        C stack = new C ("Stack");
        new C ("Heap");
        global = new C ("Global");
        C null_object;
        null_object.toString (); // SIGSEGV
    }

Then no destructors are called at all.  A signal-handling patch would probably also be accepted into Phobos if it works in both Windows and Linux; be certain that if the GC destruction causes another signal thrown, that it can recover and continue.
May 10, 2005
In article <d5r662$1s9o$1@digitaldaemon.com>, Jarrett Billingsley says...
>
>So.. when else are we supposed to release these other resources?  The dtor seems like a rather logical place to do this, especially if these resources are created in the ctor..

Welcome to GC hell.

In many (possibly most) cases you can use an auto class/variable, which guarantees to run the dtor when it goes out of scope. However, this is no help when you've got references with unpredictable lifetimes. As I understand the rules for auto, you can't write a refcounting smart pointer in D.

GC has its place and is a great help when you don't care about timing, but it's emphatically NOT a substitute for generalized RAII, and it's usually unsuitable for managing any resources except memory. This is (pretty much the only) thing keeping me from switching from C++ to D.

cheers,
Mike


May 10, 2005
In article <d5r87a$1tuj$1@digitaldaemon.com>, Burton Radons says...
>
>When run, this prints "DELETED Stack!" and "DELETED Heap!", leaving the global undeleted.  That's because the GC DOES try to clean up after itself but calls the wrong function - instead of calling collectNoStack (which still scans static data), it should call a function that does nothing but call destructors in all the allocated objects, which would be a very fast pass.

So long as there's a rule that dtors should never expect contained objects to exist, I agree.  And given that the point of dtors in a GC language are to release non-memory resources, this does seem reasonable.


Sean


May 10, 2005
Sean Kelly wrote:

> In article <d5r87a$1tuj$1@digitaldaemon.com>, Burton Radons says...
> 
>>When run, this prints "DELETED Stack!" and "DELETED Heap!", leaving the global undeleted.  That's because the GC DOES try to clean up after itself but calls the wrong function - instead of calling collectNoStack (which still scans static data), it should call a function that does nothing but call destructors in all the allocated objects, which would be a very fast pass.
> 
> 
> So long as there's a rule that dtors should never expect contained objects to
> exist, I agree.  And given that the point of dtors in a GC language are to
> release non-memory resources, this does seem reasonable.

That's no different than the present situation.

Does generational collect allow this kind of situation:

   class A { }
   class B { A a; }

   void main ()
   {
       (new B).a = new A;
   }

Where "A" is deleted in one collection pass but "B" is preserved for a later pass - or will it always collect "B" first or at the same time as "A"?  Because if the latter, then the situation can be made more sane by mandating that destructors are called in a pass before the data is freed.  That way all pointers remain legal in the destructors.  They could even call methods on one another, but no resurrection.

I don't know whether Walter would be amenable to putting that kind of requirement in the standard; I recommended it a couple years back but I can't remember what he responded with.  I don't really know anything about garbage collectors altogether.
« First   ‹ Prev
1 2 3