www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 2834] New: Struct Destructors are not called by the GC, but called on explicit delete.

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2834

           Summary: Struct Destructors are not called by the GC, but called
                    on explicit delete.
           Product: D
           Version: 2.027
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Keywords: spec
          Severity: minor
          Priority: P3
         Component: DMD
        AssignedTo: bugzilla digitalmars.com
        ReportedBy: sandford jhu.edu


According to the spec: [Struct] "Destructors are called when an object goes out
of scope. Their purpose is to free up resources owned by the struct object."
And while the heap is always 'in scope', it does delete structs which arguably
places them out of scope. Note that an explicit call to delete will run the
destructor. At a minimum, the spec should be updated to clearly reflect this
limitation. Since memory leaks, open files, etc will probably occur when a
struct with a postblit is manually allocated directly on the heap, instead of
on the stack or as part of an object, this issue might warrant a compiler
warning/error (i.e. an explicit cast is required).


-- 
Apr 14 2009
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2834


Rob Jacques <sandford jhu.edu> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrei metalanguage.com


--- Comment #1 from Rob Jacques <sandford jhu.edu> 2010-07-09 23:20:01 PDT ---
*** Issue 4442 has been marked as a duplicate of this issue. ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 09 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2834



--- Comment #2 from Rob Jacques <sandford jhu.edu> 2010-07-09 23:22:39 PDT ---
From Issue 4442:
Example brought up by Sean Kelly in private correspondence:

struct S1{ ~this() { writeln("dtor"); } }
void main() {
    auto a = S1();
    auto b = new S1();
    delete b;
    auto c  = new S1();
    c = null;
    GC.collect();
}

"dtor" is only printed twice.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 09 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2834


nfxjfg gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |nfxjfg gmail.com


--- Comment #3 from nfxjfg gmail.com 2010-07-10 00:00:11 PDT ---
Gc finalization is not deterministic. You can't expect it to be called.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 10 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2834


Sean Kelly <sean invisibleduck.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |sean invisibleduck.org


--- Comment #4 from Sean Kelly <sean invisibleduck.org> 2010-07-10 08:40:16 PDT
---
What about structs whose memory are freed by the GC?  Would you expect their
dtors to be called?  They aren't.  Try allocating ten million structs in a
loop, not one "dtor" line will print.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 10 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2834



--- Comment #5 from Sean Kelly <sean invisibleduck.org> 2010-07-10 08:41:54 PDT
---
Fixing this will probably be fairly involved.  The GC will have to store a
TypeInfo reference for each block that needs to be finalized.  The best
approach may be to integrate this with precise scanning, since that requires
detailed type info too.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 10 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2834


bearophile_hugs eml.cc changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bearophile_hugs eml.cc


--- Comment #6 from bearophile_hugs eml.cc 2010-07-11 15:16:07 PDT ---
For the moment the compiler can show a warning when the code allocates on the
heap a struct that has a destructor.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 11 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2834



--- Comment #7 from bearophile_hugs eml.cc 2010-07-11 17:24:58 PDT ---
One case where struct destructors are not called, in this situation it seems
simpler for the GC to know what destructors to call:


import core.memory: GC;
import core.stdc.stdio: printf;
struct Foo {
    int x;
    this(int xx) { this.x = xx; }
    ~this() { printf("Foo dtor x: %d\n", x); }
}
void main() {
    Foo[] a;
    a.length = 2;
    a[0].x = 1;
    a[1].x = 2;
    // delete a;
}


(I am not sure, but a type information can be useful in arrays, maybe to fix
bug 2095 too.)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 11 2010
prev sibling next sibling parent reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2834


Max Samukha <samukha voliacable.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |samukha voliacable.com


--- Comment #8 from Max Samukha <samukha voliacable.com> 2010-11-18 03:39:17
PST ---
So what is the verdict? Should we simply specify that struct destructors are
not automatically called except in RAII and remove the struct-in-class special
case?

BTW, there are other problems (serious IMO):

auto ss = new S[10];
ss.length = 5;
delete ss; 

Destructors are not called on the last 5 elements.

----
auto ss = new S[10];
ss ~= ss;
delete ss;

We have a nasty problem when destructors are called on the appended elements
because postblits was not run for them during append.

etc

Essentially, operations on arrays of structs with postblits/dtors defined are
currently unusable.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 18 2010
parent reply Sean Kelly <sean invisibleduck.org> writes:
<d-bugmail puremagic.com> wrote:
 http://d.puremagic.com/issues/show_bug.cgi?id=2834
 
 
 Max Samukha <samukha voliacable.com> changed:
 
            What    |Removed                     |Added
 ----------------------------------------------------------------------------
                  CC|                           
 |samukha voliacable.com
 
 
 --- Comment #8 from Max Samukha <samukha voliacable.com> 2010-11-18
 03:39:17 PST ---
 So what is the verdict? Should we simply specify that struct
 destructors are
 not automatically called except in RAII and remove the struct-in-class
 special
 case?
 
 BTW, there are other problems (serious IMO):
 
 auto ss = new S[10];
 ss.length = 5;
 delete ss; 
 
 Destructors are not called on the last 5 elements.
 
 ----
 auto ss = new S[10];
 ss ~= ss;
 delete ss;
 
 We have a nasty problem when destructors are called on the appended
 elements
 because postblits was not run for them during append.
 
 etc
 
 Essentially, operations on arrays of structs with postblits/dtors
 defined are
 currently unusable.

I think this is unavoidable. Consider: auto a = new T[5]; auto b = a[4..5]; a.length = 4; We can't safely destroy a[4] because it's aliased. Also, since there's no concept of an owner reference vs an alias, modifying the length of b could screw up a as well. For this and other reasons I'm inclined to withdraw this issue, and declare that since structs are value types they won't be automatically destroyed when collected by the GC or when held in arrays.
Nov 21 2010
parent Max Samukha <spambox d-coding.com> writes:
On 11/21/2010 08:20 PM, Sean Kelly wrote:
 <d-bugmail puremagic.com>  wrote:
 http://d.puremagic.com/issues/show_bug.cgi?id=2834


 Max Samukha<samukha voliacable.com>  changed:

             What    |Removed                     |Added
 ----------------------------------------------------------------------------
                   CC|
 |samukha voliacable.com


 --- Comment #8 from Max Samukha<samukha voliacable.com>  2010-11-18
 03:39:17 PST ---
 So what is the verdict? Should we simply specify that struct
 destructors are
 not automatically called except in RAII and remove the struct-in-class
 special
 case?

 BTW, there are other problems (serious IMO):

 auto ss = new S[10];
 ss.length = 5;
 delete ss;

 Destructors are not called on the last 5 elements.

 ----
 auto ss = new S[10];
 ss ~= ss;
 delete ss;

 We have a nasty problem when destructors are called on the appended
 elements
 because postblits was not run for them during append.

 etc

 Essentially, operations on arrays of structs with postblits/dtors
 defined are
 currently unusable.

I think this is unavoidable. Consider: auto a = new T[5]; auto b = a[4..5]; a.length = 4; We can't safely destroy a[4] because it's aliased. Also, since there's no concept of an owner reference vs an alias, modifying the length of b could screw up a as well. For this and other reasons I'm inclined to withdraw this issue, and declare that since structs are value types they won't be automatically destroyed when collected by the GC or when held in arrays.

I agree that correct automatic struct destruction is impossible without significant changes to arrays/slices/GC.
Nov 22 2010
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2834



--- Comment #9 from Max Samukha <samukha voliacable.com> 2010-11-18 03:59:12
PST ---
(In reply to comment #8)
 We have a nasty problem when destructors are called on the appended elements
 because postblits was not run for them during append.

I meant the problem is the destructors called on objects that have not been postblitted. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 18 2010