[ X Files @ 10.02.2005. 12:53 ] @
Pozdrav,

Primeri koji sam dole naveo (3 komada) su sa C++Builder6, a druga
dva mi daju neocekivane rezultate. Da li ima neki dobrovoljac da
stvar isproba i na drugim kompajlerima da uporedimo rezultate. Bilo
bi dobro i neko sa Delphi-jem, bas me zanima! Nece biti tesko preneti
kod, vrlo je jednostavno.

O cemu se radi. C++ po standardu nema 'finally' komandu, ali je ipak
svi kao ekstenziju isporucuju uz kompajler. Dakle, 'finally' bi treralo da
*u svakom slucaju izvrsi blok* bez obzira sta se desilo u 'try':
Code:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
   try
   {
      return;
   }
   __finally
   {
      ShowMessage( "Izvrseno bez obzira na return!" );
   }
}

Ali:

void __fastcall TForm1::Button2Click(TObject *Sender)
{
   try
   {
      try
      {
         return;
      }
      catch ( ... )
      {
      }
   }
   __finally
   {
      ShowMessage( "Nije izvrseno?!" );
   }
}

Takodje:

void __fastcall TForm1::Button3Click(TObject *Sender)
{
   try
   {
      try
      {
         // proizvedite neki izuzetak
         int x = StrToInt( "nije_broj" );
      }
      catch ( ... )
      {
         return;
      }
   }
   __finally
   {
      ShowMessage( "Nije izvrseno?!" );
   }
}

Desilo se da '__finally' nije izvrsen. U C++ se koristi cuvena
RAII tehnika da se osigura 'čišćenje' ako nesto krene lose -
to znam, ali me zanima da li je i kod drugih kompajlera stvar
kao u ovim primerima.


[Ovu poruku je menjao X Files dana 01.11.2012. u 19:33 GMT+1]
[ Dragi Tata @ 10.02.2005. 12:59 ] @
__finally uopšte nije deo C++a (lepo si rekao za RAII), a postoji konstrukcija __try... __finally pod Windows-om, takozvani SEH, koji može da se koristi i iz C-a, ali to je nešto sasvim drugo.
[ X Files @ 10.02.2005. 13:21 ] @
Ma, da - znam da nema 'finally' jos uvek u C++ standardu,
ali mislim da ne postoji C++ kompjler koji to nije uveo kao
ekstenziju. Zanima me kako se drugi kompajleri snalaze sa
pomenutim primerima.

A sto se tice RAII, to je obavezno za profi programe, ja ga
koristim na puno mesta, a najkarakteristicnije je kod
'kriticnih sekcija', npr:

Code:


// --- H ---
class CSLock
{
public:
   LPCRITICAL_SECTION fcs;

   CSLock( LPCRITICAL_SECTION acs ) : fcs( acs )
   { if ( fcs ) EnterCriticalSection( fcs ); }

   ~CSLock()
   { if ( fcs ) LeaveCriticalSection( fcs ); }
};

// --- CPP ---

// KONSTRUKTOR
{
   InitializeCriticalSection( &MyCriticalSection );
}
// DESTRUKTOR
{
   DeleteCriticalSection( &MyCriticalSection );
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
   CSLock lock( &MyCriticalSection );
   // Bez obzira sta se desilo, nece doci do dead-locka!
   ShowMessage( "DoSomething()" );
}



[ X Files @ 10.02.2005. 13:23 ] @
... zaboravih, jos u nekom header-u, treba:
Code:

CRITICAL_SECTION MyCriticalSection;


... naravno!
[ Dragi Tata @ 10.02.2005. 13:30 ] @
Citat:
X Files: Ma, da - znam da nema 'finally' jos uvek u C++ standardu,
ali mislim da ne postoji C++ kompjler koji to nije uveo kao
ekstenziju.


Pa ako pogledaš dva najpopularnija kompajlera, VC++ ga ima samo u "managed" modu, a GCC ga koliko znam nema uopšte.

A nema ni planova da se finally uvede u standard - jednostavno, nepotrebno je.
[ vlaiv @ 13.02.2005. 00:09 ] @
Ne znam da li je uopste u pitanju sledece (sto se samog posta tice) ali mene licno interesuje:

U druga dva primera __finally se nije izvrsio zato sto postoji catch statement, a kompajler je skontao da kad je Exception handle-ovan on treba da odradi return?
[ NastyBoy @ 13.02.2005. 02:02 ] @
Ovaj sluchaj je vec prijavljen u bug-listu, ali Borland ne nudi reshenje za to :
http://qc.borland.com/wc/qcmain.aspx?d=4249

Izgleda da je bag u preranoj terminaciji exception bloka.
Interesantno, jer da kad zamenish onaj tvoj "bagoviti" kod sa ovim :

Code:

void __fastcall TForm1::Button2Click(TObject *Sender)
{
  try
  {
    try
    {
      //return;
      int i=0; int j=1; int r=j/i;
    }
    catch ( ... )
    {
      ShowMessage("Deljenje nulom");
    }
  }
  __finally
  {
    ShowMessage( "Sada je izvrsheno? Zato shto ga je catch uhvatio, ili zato shto ga        return nije izbacio van bloka prerano???" );
  }
}


.... __finally se izvrshava. Chak i kada nije bachen exception, __finally radi korektno.

Da konachno prepishemo ovo Borlandu na teret? :)
[ leka @ 20.02.2005. 19:16 ] @
X Files, ista prica kao sa MFC CKlasama je i ovde - Borlandove TKlase rade UGLAVNOM samo tamo gde su Borlandovi kompajleri . Kazem uglavnom zato sto postoji OpenCLX koji nisam pogledao, a i ne znam da li se moze koristiti uz neki C++ kompajler... Dakle prica o "drugim kompajlerima" kada je ovo gore navedeno u pitanju (TForm recimo, ili TObject) ne stoji...