Thread overview
missing calls to destructors
Feb 11, 2004
one_mad_alien
Feb 18, 2004
Matthew
Jul 19, 2004
Walter
February 11, 2004
Is this the correct behaviour for dmd 0.79 ?
any class that implements an interface or has a manual constructor
does not get its destuctor called on exit
as other objects do.
example:
-------------------------------------------
import std.c.stdio;
import object;
import std.asserterror;
import std.c.windows.com;
import std.gc;

interface IBar : IUnknown {
extern(Windows) void check();
}

class CBar : ComObject, IBar
{
private static int nextId = 0;
private static int getId() { return nextId++; }
private int id;
private int _val;
this( int val ) {
id = getId();
_val = val;
printf( "Bar::Bar(%d):%d\n", id, _val );
}
~this() {
printf( "Bar::~Bar(%d):%d\n", id, _val );
}
extern(Windows) void check() {
printf( "Bar(%d):%d::check()\n", id, _val );
}
}

class Foo {
private static int nextId = 0;
private static int getId() { return nextId++; }

private int id;
private int _val;
this( int val ) {
id = getId();
_val = val;
printf( "Foo::Foo(%d):%d\n", id, _val );
}
~this() {
printf( "Foo::~Foo(%d):%d\n", id, _val );
}
}


class Manual : Foo
{
this( int val ) { super(val); }
new( uint sz )
{
void* p;
p = std.c.stdlib.malloc(sz);
if (!p) { throw new Exception("Out of memory"); }
std.gc.addRange(p, p + sz);
printf( "Manual::Manual(%p)\n", p );
return p;
}

delete(void* p)
{
printf( "Manual::~Manual(%p)\n", p );
if (p){
std.gc.removeRange(p);
std.c.stdlib.free(p);
}
}
}

int main( char[][] args )
{
IBar getIbar() { return new CBar(400); }

try {
auto Foo f = new Foo( 100 );
Foo fred1 = new Foo( 201 );
Foo fred2 = new Manual( 202 );
CBar b    = new CBar( 300 );
IBar c = getIbar();
b.check();
c.check();
} catch ( Exception e ) {
printf( "Caught Exception(%.*s)\n", e.toString() );
} catch ( AssertError ae ) {
printf( "Caught AssertError(%.*s)\n", ae.toString() );
} catch ( Object o ) {
printf( "Caught Object(%.*s)\n", o.toString() );
}
return 0;
}
/*
/// this code run on dmd 0.79 outputs
Foo::Foo(0):100
Foo::Foo(1):201
Manual::Manual(00840F6C)
Foo::Foo(2):202
Bar::Bar(0):300
Bar::Bar(1):400
Bar(0):300::check()
Bar(1):400::check()
Foo::~Foo(0):100
Foo::~Foo(1):201
*/



February 18, 2004
Can you, and all other posters, convert tabs to spaces before posting code. There's simply no way I'm going to raise the mental effort to try and parse your code, nor the physical effort to reformat it. I would assume that just about everyone else feels the same, hence the lack of response to your post.

Any decent IDDE can do this, or you can do it using the untabify.pl script available from http://synsoft.org/perl.html

<one_mad_alien@hotmail.com> wrote in message news:c0dokp$4gt$1@digitaldaemon.com...
> Is this the correct behaviour for dmd 0.79 ?
> any class that implements an interface or has a manual constructor
> does not get its destuctor called on exit
> as other objects do.
> example:
> -------------------------------------------
> import std.c.stdio;
> import object;
> import std.asserterror;
> import std.c.windows.com;
> import std.gc;
>
> interface IBar : IUnknown {
> extern(Windows) void check();
> }
>
> class CBar : ComObject, IBar
> {
> private static int nextId = 0;
> private static int getId() { return nextId++; }
> private int id;
> private int _val;
> this( int val ) {
> id = getId();
> _val = val;
> printf( "Bar::Bar(%d):%d\n", id, _val );
> }
> ~this() {
> printf( "Bar::~Bar(%d):%d\n", id, _val );
> }
> extern(Windows) void check() {
> printf( "Bar(%d):%d::check()\n", id, _val );
> }
> }
>
> class Foo {
> private static int nextId = 0;
> private static int getId() { return nextId++; }
>
> private int id;
> private int _val;
> this( int val ) {
> id = getId();
> _val = val;
> printf( "Foo::Foo(%d):%d\n", id, _val );
> }
> ~this() {
> printf( "Foo::~Foo(%d):%d\n", id, _val );
> }
> }
>
>
> class Manual : Foo
> {
> this( int val ) { super(val); }
> new( uint sz )
> {
> void* p;
> p = std.c.stdlib.malloc(sz);
> if (!p) { throw new Exception("Out of memory"); }
> std.gc.addRange(p, p + sz);
> printf( "Manual::Manual(%p)\n", p );
> return p;
> }
>
> delete(void* p)
> {
> printf( "Manual::~Manual(%p)\n", p );
> if (p){
> std.gc.removeRange(p);
> std.c.stdlib.free(p);
> }
> }
> }
>
> int main( char[][] args )
> {
> IBar getIbar() { return new CBar(400); }
>
> try {
> auto Foo f = new Foo( 100 );
> Foo fred1 = new Foo( 201 );
> Foo fred2 = new Manual( 202 );
> CBar b    = new CBar( 300 );
> IBar c = getIbar();
> b.check();
> c.check();
> } catch ( Exception e ) {
> printf( "Caught Exception(%.*s)\n", e.toString() );
> } catch ( AssertError ae ) {
> printf( "Caught AssertError(%.*s)\n", ae.toString() );
> } catch ( Object o ) {
> printf( "Caught Object(%.*s)\n", o.toString() );
> }
> return 0;
> }
> /*
> /// this code run on dmd 0.79 outputs
> Foo::Foo(0):100
> Foo::Foo(1):201
> Manual::Manual(00840F6C)
> Foo::Foo(2):202
> Bar::Bar(0):300
> Bar::Bar(1):400
> Bar(0):300::check()
> Bar(1):400::check()
> Foo::~Foo(0):100
> Foo::~Foo(1):201
> */
>
>
>


July 19, 2004
Overriding operators new and delete mean that you're in charge of the memory allocation/deallocation for it, not the gc. I don't see any where in your code where fred2 is deleted.

<one_mad_alien@hotmail.com> wrote in message news:c0dokp$4gt$1@digitaldaemon.com...
> Is this the correct behaviour for dmd 0.79 ?
> any class that implements an interface or has a manual constructor
> does not get its destuctor called on exit
> as other objects do.
> example:
> -------------------------------------------
> import std.c.stdio;
> import object;
> import std.asserterror;
> import std.c.windows.com;
> import std.gc;
>
> interface IBar : IUnknown {
> extern(Windows) void check();
> }
>
> class CBar : ComObject, IBar
> {
> private static int nextId = 0;
> private static int getId() { return nextId++; }
> private int id;
> private int _val;
> this( int val ) {
> id = getId();
> _val = val;
> printf( "Bar::Bar(%d):%d\n", id, _val );
> }
> ~this() {
> printf( "Bar::~Bar(%d):%d\n", id, _val );
> }
> extern(Windows) void check() {
> printf( "Bar(%d):%d::check()\n", id, _val );
> }
> }
>
> class Foo {
> private static int nextId = 0;
> private static int getId() { return nextId++; }
>
> private int id;
> private int _val;
> this( int val ) {
> id = getId();
> _val = val;
> printf( "Foo::Foo(%d):%d\n", id, _val );
> }
> ~this() {
> printf( "Foo::~Foo(%d):%d\n", id, _val );
> }
> }
>
>
> class Manual : Foo
> {
> this( int val ) { super(val); }
> new( uint sz )
> {
> void* p;
> p = std.c.stdlib.malloc(sz);
> if (!p) { throw new Exception("Out of memory"); }
> std.gc.addRange(p, p + sz);
> printf( "Manual::Manual(%p)\n", p );
> return p;
> }
>
> delete(void* p)
> {
> printf( "Manual::~Manual(%p)\n", p );
> if (p){
> std.gc.removeRange(p);
> std.c.stdlib.free(p);
> }
> }
> }
>
> int main( char[][] args )
> {
> IBar getIbar() { return new CBar(400); }
>
> try {
> auto Foo f = new Foo( 100 );
> Foo fred1 = new Foo( 201 );
> Foo fred2 = new Manual( 202 );
> CBar b    = new CBar( 300 );
> IBar c = getIbar();
> b.check();
> c.check();
> } catch ( Exception e ) {
> printf( "Caught Exception(%.*s)\n", e.toString() );
> } catch ( AssertError ae ) {
> printf( "Caught AssertError(%.*s)\n", ae.toString() );
> } catch ( Object o ) {
> printf( "Caught Object(%.*s)\n", o.toString() );
> }
> return 0;
> }
> /*
> /// this code run on dmd 0.79 outputs
> Foo::Foo(0):100
> Foo::Foo(1):201
> Manual::Manual(00840F6C)
> Foo::Foo(2):202
> Bar::Bar(0):300
> Bar::Bar(1):400
> Bar(0):300::check()
> Bar(1):400::check()
> Foo::~Foo(0):100
> Foo::~Foo(1):201
> */
>
>
>