On Sat, 10 Jul 2010 01:06:39 -0400, Jonathan M Davis <jmdavisp...@gmail.com> wrote:

I thought that classes always went on the heap and that structs always went on the stack - so allocating structs with new wouldn't work. Also, I thought that delete was deprecated if not outright removed from D. And yet, we have a new bug that Andrei reported about destructors for structs not working correctly when they're allocated with new (and delete is being used to destroy it in the code
in the report).

http://d.puremagic.com/issues/show_bug.cgi?id=4442

Code from bug report:

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

Am I missing something here? TDPL was quite clear that classes were reference types and structs were value types, and here we appear to have a struct used as a reference type. Is this some sort of feature from outside of SafeD, or is it a feature that was supposed to be removed but hasn't yet, or what? I know that TDPL doesn't cover everything and that what dmd does doesn't always match it yet, but from what I understood from reading TDPL, the code above shouldn't compile at all since it's using a struct like a class and is using the supposedy
defunct delete operator.

structs on the heap are a necessity. Classes are too heavyweight for storing things like graph/tree nodes, one does not need the vtable/lock when one is concerned about performance. Switching from classes to structs on dcollections' nodes saved quite a bit of execution time.

The problem I see here is allowing the GC to manage the memory of a struct and having the GC responsible for calling the destructor of something that it can't possibly know the destructor of. Classes have their destructor stored in the vtable, which is how the GC gets at it, the GC has no typeinfo to go on. Even with the proposed precise scanning, I think the GC only stores basic pointer maps, it does not have access to the full TypeInfo.

I'd say it's a program error to have a GC allocated struct with a destructor. It should be made a compiler error too. There are ways to have structs stored on the heap and have destructors called on them.

Also, the example given in the bug report is very simplistic, just to demonstrate the problem. Does anyone have a good use case for struct dtors being called when allocated by the GC? All of the struct dtors I've seen assume they are stack-allocated.

-Steve

Reply via email to