c++ - C++Builder does not call destructor on throw-catch-continue -


for code:

#include <stdio.h>  int constrcalls=0, destrcalls=0;  struct z {     z() { constrcalls++; }     ~z() { destrcalls++; } };  int main(int argc, char**) {    bool startup= true;        {       z z;        try       {           if( startup )           {               startup= false;               throw( 1 );           }           else           {               break;           }       }       catch(int)       {           continue;       }    }    while(true);     printf( "constrcalls=%d destrcalls=%d", constrcalls, destrcalls);    return 0; } 
  • g++ output "constrcalls=2 destrcalls=2", ok

  • embarcadero c++builder 2010, c++builder 10 seattle output "constrcalls=2 destrcalls=1", after throw-catch-continue destructor not called!

can c++builder works right?

thanks.

sadly...

the c++builder 6, rad studio 2009 , xe7 update 1, c++ compiler generates bad exception handling code (and in likelihood compilers in between--those compilers current have access to). when exception thrown, stack unwind code has been observed to:

  • crash access violation
  • fail execute destructors when should
  • leak memory
  • fire destructors twice

this makes impossible produce reliable, exception-safe, c++ software compiler.

take @ c++ compiler exception handling broken further details.

this section "not firing destructors when should":

the following button onclick event handler constructs temporary count objects within try/catch scope. count objects keep track of number of live instances in count variable.

as invariant number of count instances should 0 following try/catch. instead fails bad stack unwind.

static int count = 0;  struct count {     count() { ++count; }     count(const count& rhs) { ++count; }     ~count( ) { --count; } };  static int __fastcall destructornotfired(int i=0, count c=count() ) {     throw exception( "destructor not fired" ); }  void __fastcall texceptionbugtestform::buttondestructornotfiredclick(tobject *sender) {     assert(count == 0);      try {         destructornotfired( destructornotfired() );     } catch ( exception& e ) {     }      if (count != 0) {         showmessage( "bad stack unwind" );     }      assert(count == 0); } 

(very similar code).

exception handling works compiling code clang++ (only 64bit c++builder != xe10).


Comments

Popular posts from this blog

get url and add instance to a model with prefilled foreign key :django admin -

css - Make div keyboard-scrollable in jQuery Mobile? -

ruby on rails - Seeing duplicate requests handled with Unicorn -