www.digitalmars.com         C & C++   DMDScript  

D - missing calls to destructors

reply one_mad_alien hotmail.com writes:
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
*/
Feb 11 2004
next sibling parent "Matthew" <matthew.hat stlsoft.dot.org> writes:
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
 */

Feb 17 2004
prev sibling parent "Walter" <newshound digitalmars.com> writes:
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
 */

Jul 19 2004