www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - scope attribute and catching exception

reply Paolo Invernizzi <arathorn fastwebnet.it> writes:
Hi all,
Someone can explain me why the scope attribute of r2 is not satisfied? It's a
bug or an expected behaviour?

Paolo

module tests.d.scopes.t02.test;

class Resource {
    static int allocated = 0;
    this( bool mustThrow = false ){
        allocated ++;
        if( mustThrow ) throw new Exception("bang");
    }
    ~this(){
        allocated --;
    }
}

void main(){
    
    
    // Why the destructor of r2 is not called when exiting the scope?
    {
        try {
            scope r1 = new Resource();
            scope r2 = new Resource(true);
        }
        catch(Exception e){}
    }
    //assert( Resource.allocated == 0); // Expected
    assert( Resource.allocated == 1 ); // What's happening
    
}
Oct 13 2008
next sibling parent reply "Denis Koroskin" <2korden gmail.com> writes:
On Mon, 13 Oct 2008 13:50:46 +0400, Paolo Invernizzi  
<arathorn fastwebnet.it> wrote:

 Hi all,
 Someone can explain me why the scope attribute of r2 is not satisfied?  
 It's a bug or an expected behaviour?

 Paolo

 module tests.d.scopes.t02.test;

 class Resource {
     static int allocated = 0;
     this( bool mustThrow = false ){
         allocated ++;
         if( mustThrow ) throw new Exception("bang");
     }
     ~this(){
         allocated --;
     }
 }

 void main(){
    // Why the destructor of r2 is not called when exiting the scope?
     {
         try {
             scope r1 = new Resource();
             scope r2 = new Resource(true);
         }
         catch(Exception e){}
     }
     //assert( Resource.allocated == 0); // Expected
     assert( Resource.allocated == 1 ); // What's happening
 }

Looks like no destructor is called if ctor throws an exception. Try throwing outside of it and see what happens.
Oct 13 2008
parent Paolo Invernizzi <arathorn fastwebnet.it> writes:
Denis Koroskin Wrote:

 Looks like no destructor is called if ctor throws an exception.
 Try throwing outside of it and see what happens.

In that case everything is ok. So it's a bug? // In this case everything it's ok { try { scope r1 = new Resource(); scope r2 = new Resource(); throw new Exception("bang"); } catch(Exception e){} } assert( Resource.allocated == 0); // Expected
Oct 13 2008
prev sibling parent reply Max Samukha <samukha voliacable.com.removethis> writes:
On Mon, 13 Oct 2008 05:50:46 -0400, Paolo Invernizzi
<arathorn fastwebnet.it> wrote:

Hi all,
Someone can explain me why the scope attribute of r2 is not satisfied? It's a
bug or an expected behaviour?

Paolo

module tests.d.scopes.t02.test;

class Resource {
    static int allocated = 0;
    this( bool mustThrow = false ){
        allocated ++;
        if( mustThrow ) throw new Exception("bang");
    }
    ~this(){
        allocated --;
    }
}

void main(){
    
    
    // Why the destructor of r2 is not called when exiting the scope?
    {
        try {
            scope r1 = new Resource();
            scope r2 = new Resource(true);
        }
        catch(Exception e){}
    }
    //assert( Resource.allocated == 0); // Expected
    assert( Resource.allocated == 1 ); // What's happening
    
}

because r2 wasn't successfully created and there is nothing to call the destructor on: class Resource { static int allocated = 0; this( bool mustThrow = false ) { scope(success) allocated++; if( mustThrow ) throw new Exception("bang"); } ~this(){ allocated --; } }
Oct 13 2008
parent reply Paolo Invernizzi <arathorn fastwebnet.it> writes:
Max Samukha Wrote:

 because r2 wasn't successfully created and there is nothing to call
 the destructor on:

I think is more complicated... see this: module tests.d.scopes.t02.test; class Resource { static int allocated = 0; this( bool mustThrow = false ){ allocated ++; if( mustThrow ) throw new Exception("bang"); } ~this(){ allocated --; } } class Factory { Resource resource(bool b=false){ return new Resource(b); } } import std.gc, std.stdio; void main(){ // In this case everything it's ok { try { scope r1 = new Resource(true); assert( false ); } catch(Exception e){} assert( Resource.allocated == 1); std.gc.fullCollect(); assert( Resource.allocated == 1 ); } Resource.allocated = 0; // In this case the destructor IS called, only on collect... { auto f = new Factory(); try { scope r1 = f.resource(true); assert( false ); } catch(Exception e){} assert( Resource.allocated == 1); std.gc.fullCollect(); assert( Resource.allocated == 0 ); // Dho! Destructor called! } }
Oct 13 2008
parent Max Samukha <samukha voliacable.com.removethis> writes:
On Mon, 13 Oct 2008 08:03:32 -0400, Paolo Invernizzi
<arathorn fastwebnet.it> wrote:

Max Samukha Wrote:

 because r2 wasn't successfully created and there is nothing to call
 the destructor on:

I think is more complicated... see this: module tests.d.scopes.t02.test; class Resource { static int allocated = 0; this( bool mustThrow = false ){ allocated ++; if( mustThrow ) throw new Exception("bang"); } ~this(){ allocated --; } } class Factory { Resource resource(bool b=false){ return new Resource(b); } } import std.gc, std.stdio; void main(){ // In this case everything it's ok { try { scope r1 = new Resource(true); assert( false ); } catch(Exception e){} assert( Resource.allocated == 1); std.gc.fullCollect(); assert( Resource.allocated == 1 ); } Resource.allocated = 0; // In this case the destructor IS called, only on collect... { auto f = new Factory(); try { scope r1 = f.resource(true); assert( false ); } catch(Exception e){} assert( Resource.allocated == 1); std.gc.fullCollect(); assert( Resource.allocated == 0 ); // Dho! Destructor called! } }

I think this is a bug.
Oct 13 2008