Board index » cppbuilder » Try, Catch or Finally?

Try, Catch or Finally?


2003-08-22 03:04:10 AM
cppbuilder27
Can anyone give me the plus and minuses of what to use in my code. What is
preferable try {} catch without finally. try{} finally (without a catch)
or use a combination?
What are the OO thoughts behind it? or just some coding guidelines. I'm
using builder v6.
Thanx for your time
Janus.
 
 

Re:Try, Catch or Finally?

"Janus smith" < XXXX@XXXXX.COM >wrote in message
Quote
Can anyone give me the plus and minuses of what to use in my code.
What is preferable try {} catch without finally. try{} finally (without
a catch) or use a combination?
Try...finally does not catch exceptions, it simply makes sure that a block
of code is always executed even if an exception is thrown. The exception
itself still exists once the finally block is finished. You still need to
use a separate catch() statement to actually catch exceptions regardless of
whether you use a finally block or not.
Gambit
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (www.grisoft.com).
Version: 6.0.510 / Virus Database: 307 - Release Date: 8/14/03
 

Re:Try, Catch or Finally?

"Janus smith" < XXXX@XXXXX.COM >wrote:
Quote
[...] or use a combination?
It really depends on your style of coding. Example #1 shows a
try/catch/finally block followed 2 try/catch blocks. They all
accomplish the same thing.
//--- Example 1 -------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Screen->Cursor = crHourGlass;
try
{
Function1();
Function2();
}
catch( Exception& E )
{
MessageDlg("Button1 Click failed : " + E.Message, mtError, TMsgDlgButtons() << mbOK, 0);
}
__finally
{
Screen->Cursor = crDefault;
}
}
//--- Could also be written as ----------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Screen->Cursor = crHourGlass;
try
{
Function1();
Function2();
Screen->Cursor = crDefault;
}
catch( Exception& E )
{
MessageDlg("Button1 Click failed : " + E.Message, mtError, TMsgDlgButtons() << mbOK, 0);
Screen->Cursor = crDefault;
}
}
//--- Could also be written as ----------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Screen->Cursor = crHourGlass;
try
{
Function1();
Function2();
}
catch( Exception& E )
{
MessageDlg("Button1 Click failed : " + E.Message, mtError, TMsgDlgButtons() << mbOK, 0);
}
Screen->Cursor = crDefault;
}
While it may appear that the use of finally with a try/catch
block is nothing more than more typing, that's not exactly true.
The finally block is guaranteed to be executed while the code
following the catch that is not inside a finally block is not.
This is important because errors other than the standard
exception can be thrown - like an eConvertError for example -
and in the above example, that wouldn't be caught.
The next example steps into Function1() and demonstrates a
try/finally block. It allows the exception (if any) to pass
back to the calling function where it can be handled by catch().
//--- Example 2 - assume button1 click from above ----
void __fastcall TForm1::Function1()
{
char* ptr = NULL; // set to NULL in case allocation fails
// because it's ok to delete NULL pointer
try
{
ptr = new char[ 100 ];
// do some stuff with ptr
}
__finally
{
delete [] ptr; // executes no matter what happens above
}
}
In the above example, if Function1() throws an exception,
Button1Click will catch it, display an error message, and
continue happily on it's merry way. However, if you have to
debug it, you won't know if Button1Click failed on Function1()
or if it failed on Function2().
Now consider this: If you duplicate the catch from Button1Click
to catch the exception in Function1() (to know where it failed),
Button1Click will still continue execution with Function2() -
not a good thing when the execution of Function2() depends on
the success of Function1().
The next example shows how to avoid this problem and it also
provides a richer error message to assist in debugging.
//--- Example 3 - assume button1 click from above ----
void __fastcall TForm1::Function1()
{
String errMessage = ""; // 'String' is shorthand for AnsiString
char* ptr = NULL; // set to NULL in case allocation fails
// because it's ok to delete NULL pointer
try
{
ptr = new char[ 100 ];
// do some stuff with ptr
}
catch( Exception& E )
{
errMessage = (AnsiString)"Function1 : " + E.Message;
}
delete [] ptr;
if( !errMessage.IsEmpty() ) throw Exception( errMessage );
}
What will happen if and exception is thrown is that it will be
caught, modified, re-thrown, and re-caught by Button1Click. The
resulting error message that gets displayed will look like this:
Button1 Click failed : Function1 failed : actual exception msg
HTH
~ JD
 

{smallsort}

Re:Try, Catch or Finally?

On Thu, 21 Aug 2003 21:04:10 +0200, "Janus smith" < XXXX@XXXXX.COM >wrote:
Quote
Can anyone give me the plus and minuses of what to use in my code. What is
preferable try {} catch without finally. try{} finally (without a catch)
or use a combination?

What are the OO thoughts behind it? or just some coding guidelines. I'm
using builder v6.

Thanx for your time

Janus.

I've done this before...
try
{
try
{
}
catch(...)
{
}
}
__finally
{
}
Hope it isn't too silly. It is pretty straight forward.
HTH,
Jeff Kish
 

Re:Try, Catch or Finally?

Jeff Kish < XXXX@XXXXX.COM >wrote:
Quote
[...] I've done this before...

try
{
try
{
}
catch(...)
{
}
}
__finally
{
}

The above example serves no purpose other than to produce more
overhead. Now, if you had multiple exception classes that you
needed to catch and if you included a catch in the out most
try block, it would make sense to do it this way.
~ JD
 

Re:Try, Catch or Finally?

"JD" < XXXX@XXXXX.COM >wrote in message
Quote
//--- Example 1 -------------------------------------
The common way to code that is to give the __finally its own try statement.
It is also customary to put the __finally block inside the try...catch
rather than outside of it, otherwise the __finally becomes redundant and
should be omitted. For example:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
try
{
Screen->Cursor = crHourGlass;
try
{
Function1();
Function2();
}
__finally
{
Screen->Cursor = crDefault;
}
}
catch( Exception& E )
{
MessageDlg("Button1 Click failed : " + E.Message, mtError,
TMsgDlgButtons() << mbOK, 0);
}
}
Quote
The finally block is guaranteed to be executed while the
code following the catch that is not inside a finally block
is not. This is important because errors other than the
standard exception can be thrown - like an eConvertError
for example - and in the above example, that wouldn't be
caught.
That statement is misleading when applied to your actual examples. Code
that follows a catch() block is always guaranteed to execute, unless the
catch() block throws another exception of its own. Since you are catching
Exception, which is the base class for *all* VCL exception, then your
catch() block will always execute regardless of what kind of VCL exception
was thrown, and as long as the catch() block does not throw another
exception, the remaining code outside of the catch() block will execute
normally.
Quote
However, if you have to debug it, you won't know
if Button1Click failed on Function1() or if it failed
on Function2().
If you are running inside the de{*word*81}, then yes you will. The de{*word*81}
will break on the exception and you will be able to see exactly where the
exception occured.
Quote
//--- Example 3 - assume button1 click from above ----
A different way to code that would be as follows:
void __fastcall TForm1::Function1()
{
char* ptr = NULL;
try
{
try
{
ptr = new char[ 100 ];
// do some stuff with ptr
}
__finally
{
delete [] ptr;
}
}
catch( Exception& E )
{
throw Exception( AnsiString(__FUNC__) + ": " + E.Message );
}
}
Gambit
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (www.grisoft.com).
Version: 6.0.510 / Virus Database: 307 - Release Date: 8/14/03
 

Re:Try, Catch or Finally?

"JD" < XXXX@XXXXX.COM >wrote in message
Quote
The above example serves no purpose other than
to produce more overhead.
Funny you should say that, considering that one of your own examples showed
pretty much the exact same thing.
Gambit
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (www.grisoft.com).
Version: 6.0.510 / Virus Database: 307 - Release Date: 8/14/03
 

Re:Try, Catch or Finally?

"Remy Lebeau \(TeamB\)" < XXXX@XXXXX.COM >wrote:
Quote
The common way to code that is to give the __finally its own
try statement. It is also customary to put the __finally
block inside the try...catch rather than outside of it,
otherwise the __finally becomes redundant and should be
omitted.
I really like your example but I tend to disagree on how
common or customary it is simply because I've never seen it
structured that way before.
Quote
[...] Since you are catching Exception, which is the base
class for *all* VCL exception,
I have to admit that I'm a bit confused about what throws what
and the corresponding catch. What exceptions are not VCL based?
Quote
>However, if you have to debug it, you won't know
>if Button1Click failed on Function1() or if it failed
>on Function2().

If you are running inside the de{*word*81}, then yes you will.
I phrased that poorly. I was thinking of a user running into
an error. The error message would pinpoint the function where
it failed and give you a headstart to tracking down the
problem.
Quote
>//--- Example 3 - assume button1 click from above ----

A different way to code that would be as follows:
[...]

throw Exception( AnsiString(__FUNC__) + ": " + E.Message );
Very handy.
~ JD
 

Re:Try, Catch or Finally?

"Remy Lebeau \(TeamB\)" < XXXX@XXXXX.COM >wrote:
Quote

>The above example serves no purpose other than
>to produce more overhead.

Funny you should say that, considering that one of your own
examples showed pretty much the exact same thing.
LOL - but mine was on purpose!!! I wanted to show that it could be used that way but that the same thing could be done without the finally block.
"Example #1 shows a try/catch/finally block followed 2 try/catch
blocks. They all accomplish the same thing."
The truth be told, I couldn't see a use for try/catch/finally
until I saw your sample.
~ JD
 

Re:Try, Catch or Finally?

"JD" < XXXX@XXXXX.COM >wrote in message
Quote
I really like your example but I tend to disagree on
how common or customary it is simply because I've
never seen it structured that way before.
The __finally construct is not often used in C++, mainly because there are
better ways to accomplish the same thing without using compiler extensions.
It is, however, used through Delphi programming. Have a look at the VCL
source code sometime, for example, it is littered with try...finally blocks.
Quote
I have to admit that I'm a bit confused about what throws
what and the corresponding catch. What exceptions are
not VCL based?
Everything that is not a descendant of the VCL Exception class. There are
basically three types of exceptions available to C++Builder developers:
1) VCL exceptions:
- based on or derived from the VCL Exception class specifically.
2) C++ exceptions:
- basically can be just about anything that is passed to 'throw', it
doesn't even have to be a class. Look at the C++ standard for more
information.
3) SEH (Structured Exceptions), aka low-level OS exceptions:
- these must be handled via a try...__except() block instead of a
try..catch() one. Look at the Win32 API documentation for more information.
Most of the SEH exceptions are translated into VCL-native exceptions by the
VCL runtime. If a C++ exception filters into VCL code, it usually gets
translated into an EExternal exception with an ExceptionCode of 0xEEFFACE,
although unhandled SEH exceptions may translate to 0xEEFFACE as well.
Gambit
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (www.grisoft.com).
Version: 6.0.512 / Virus Database: 309 - Release Date: 8/19/03
 

Re:Try, Catch or Finally?

"JD" < XXXX@XXXXX.COM >wrote in message news:3f46654b$ XXXX@XXXXX.COM ...
Quote

"Remy Lebeau \(TeamB\)" < XXXX@XXXXX.COM >wrote:
>
>>The above example serves no purpose other than
>>to produce more overhead.
>
>Funny you should say that, considering that one of your own
>examples showed pretty much the exact same thing.

LOL - but mine was on purpose!!! I wanted to show that it could be used that way but that the same thing could be done without the
finally block.

"Example #1 shows a try/catch/finally block followed 2 try/catch
blocks. They all accomplish the same thing."

The truth be told, I couldn't see a use for try/catch/finally
until I saw your sample.

~ JD

Wait a minute!
The __finally below is redundant but
are you saying the following is valid syntax? :
{
try
{
;
}
catch( Exception& E )
{
;
}
__finally // Line 47
{
;
}
} // Line 51
BCB5 gives the following errors:
[C++ Error] Unit1.cpp(47): E2188 Expression syntax
[C++ Error] Unit1.cpp(51): E2379 Statement missing ;
Am I missing something?
It has been my understanding that there is
try/catch or try/finally at the same scope level
but try/catch/finally is both redundant and illegal!
Correct me if I am wrong.
Todd
 

Re:Try, Catch or Finally?

"Todd Brylski" < XXXX@XXXXX.COM >wrote:
Quote
[...] Am I missing something?
Yes. The fact that I put something out there that I hadn't used or tested!! <g>
I only intended to show that using finally *could* be redundant
and I was unaware that it was illegal because I would never code
it that way anyway.
~ JD
 

Re:Try, Catch or Finally?

On 22 Aug 2003 08:22:21 -0700, "JD" < XXXX@XXXXX.COM >wrote:
Quote

Jeff Kish < XXXX@XXXXX.COM >wrote:
>[...] I've done this before...
>
>try
>{
>try
>{
>}
>catch(...)
>{
>}
>}
>__finally
>{
>}
>

The above example serves no purpose other than to produce more
overhead. Now, if you had multiple exception classes that you
needed to catch and if you included a catch in the out most
try block, it would make sense to do it this way.

~ JD
OK.. its been a while, but I seemed to remember that I could not do
try{}catch{}finally{} because of syntax errors.
In this case the finally would be a catchall/clean up place for stuff
you need to do regardless of whether or not you threw exceptions (so
you don't always need the finally), and of course the catch is to
"catch" exceptions.
I also seem to remember putting multiple trys inside the finally, like
if I am doing a lot of processing in separate sql statements.
Thanks for the discussion and clarification,
Jeff Kish