Allocating structs with new?

Robert Jacques sandford at jhu.edu
Fri Jul 9 23:31:18 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.
>
> - Jonathan M Davis

A new statement can also allocate value types on the heap and return a  
pointer to them. For example, the type of b and c is S1* and the GC  
doesn't know about C's destructor. Please refer to the D spec on new  
(http://www.digitalmars.com/d/2.0/expression.html#NewExpression) or TDPL  
page 51. Both state that any type can be used with new; no limitations  
with regard to reference or non-reference types are mentioned. Also, on  
page 269 of TDPL there is an example of containing a Node*.

As for the bug, it's actually somewhat old. Issue 2834 was filed back in  
April of 09 - Struct Destructors are not called by the GC, but called on  
explicit delete. And this is a bug in the spec, not DMD; the only way to  
run struct destructors from the GC is to add vtables to them or hidden in  
the GC (i.e. to make them classes). By the way, structs inside of classes  
do get their destructors called.

As for delete and clear, the deprecation/transition is still in progress.  
clear exists, but delete is not deprecated yet.


More information about the Digitalmars-d mailing list