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