Allocating structs with new?

Steven Schveighoffer schveiguy at yahoo.com
Mon Jul 12 05:27:21 PDT 2010


On Sat, 10 Jul 2010 01:06:39 -0400, Jonathan M Davis  
<jmdavisprog at 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


More information about the Digitalmars-d mailing list