Try catch blocks - can multiple methods share a single try/catch combination? 
Author Message
 Try catch blocks - can multiple methods share a single try/catch combination?

I have a class with some 60 methods that need to do I/O or memory
allocation.  Each method has its own "try" and "catch" blocks which do very
similar things.  Because the code needs to be compiled under VC++ 4.1 (to
produce the Windows 95/NT version), VC++ 1.5 (to produce the Windows 3.1
version) and Watcom C++ to produce an NLM version, these try and catch
blocks also have #ifdefs in them and they consume a substantial amount of
the source code when added together.

Is there a way to associate a single set of try and catch blocks with
multiple methods?

Thanks.

Jerry



Sun, 24 Sep 2000 03:00:00 GMT  
 Try catch blocks - can multiple methods share a single try/catch combination?

Nope, don't think so.
The universal bandaid is to make a macro for try and for catch.
I tend to do a very limited set of things in catch, so I have one macro for
each standard catch behavior.
For example, here's my generic try, and the catch, which logs the error and
puts up a dialog box:

____________________________________
// Generic try; macro'd so that we can add behavior here if necessary
// Must be followed by a block, followed by a TRK_CATCH_xxx variant

#define TRK_TRY_MARK try { // Tracker::Exedll::MarkLog();

// Logs error and displays it in dialog box.

#define TRK_CATCH_DISPLAY } \
 catch(_com_error &E)
 Tracker::Exedll::DisplayThrow(&E,_trk_block_sign,__LINE__); } \
 catch(ElException &E)
 Tracker::Exedll::DisplayThrow(&E,_trk_block_sign,__LINE__); }
____________________________________

Example:

void UserDlg::AddAUser()
{
    TRK_TRY_MARK
    {
        // do some stuff which may throw
    }
    TRK_CATCH_DISPLAY

Quote:
}

____________________________________

There's no way to make this really clean, syntactically; I normally like
macros to act like statements or expressions and these do not.

If you need to add per-usage behavior to the catch, you'll need to add an
END_CATCH macro, also.

While these kinds of macros are ugly, I think they're far superior to having
redundant code which must be kept in sync.

--

(remove the xxx from reply address)


Quote:
>I have a class with some 60 methods that need to do I/O or memory
>allocation.  Each method has its own "try" and "catch" blocks which do very
>similar things.  Because the code needs to be compiled under VC++ 4.1 (to
>produce the Windows 95/NT version), VC++ 1.5 (to produce the Windows 3.1
>version) and Watcom C++ to produce an NLM version, these try and catch
>blocks also have #ifdefs in them and they consume a substantial amount of
>the source code when added together.

>Is there a way to associate a single set of try and catch blocks with
>multiple methods?

>Thanks.

>Jerry



Sun, 24 Sep 2000 03:00:00 GMT  
 Try catch blocks - can multiple methods share a single try/catch combination?

Something that I've done from time to time when I want the same catch
mechanism in multiple places is to write my extensive try/catch block in a
"testbed" type of function that accepts a function pointer as an argument.
The function pointer is then called from within the try{}.

E.g.,

// Functions to be executed
void DoOneThing() ;
void DoAnotherThing() ;
void DoYetAnotherThing() ;

// Testbed which accepts a function to execute within a try/catch block
void TestBed( void (*pFn)() )
{
    try {
        (*pFn)() ;
    }
    catch( exceptType1 & ex1 )
    { /* handle ex1 */ }
    catch( exceptType2 & ex2 )
    { /* handle ex2 */ }
    catch( exceptType3 & ex3 )
    { /* handle ex3 */ }
    catch( ... )
    { /* handle the rest */ }

Quote:
}

void main()
{
    TestBed( DoOneThing ) ;
    TestBed( DoAnotherThing ) ;
    TestBed( DoYetAnotherThing ) ;

Quote:
}

> Nope, don't think so.
> The universal bandaid is to make a macro for try and for catch.
> I tend to do a very limited set of things in catch, so I have one macro for
> each standard catch behavior.
> For example, here's my generic try, and the catch, which logs the error and
> puts up a dialog box:

> ____________________________________
> // Generic try; macro'd so that we can add behavior here if necessary
> // Must be followed by a block, followed by a TRK_CATCH_xxx variant

> #define TRK_TRY_MARK try { // Tracker::Exedll::MarkLog();

> // Logs error and displays it in dialog box.

> #define TRK_CATCH_DISPLAY } \
>  catch(_com_error &E)
>  Tracker::Exedll::DisplayThrow(&E,_trk_block_sign,__LINE__); } \
>  catch(ElException &E)
>  Tracker::Exedll::DisplayThrow(&E,_trk_block_sign,__LINE__); }
> ____________________________________

> Example:

> void UserDlg::AddAUser()
> {
>     TRK_TRY_MARK
>     {
>         // do some stuff which may throw
>     }
>     TRK_CATCH_DISPLAY
> }

> ____________________________________

> There's no way to make this really clean, syntactically; I normally like
> macros to act like statements or expressions and these do not.

> If you need to add per-usage behavior to the catch, you'll need to add an
> END_CATCH macro, also.

> While these kinds of macros are ugly, I think they're far superior to having
> redundant code which must be kept in sync.

> --

> (remove the xxx from reply address)



> >I have a class with some 60 methods that need to do I/O or memory
> >allocation.  Each method has its own "try" and "catch" blocks which do very
> >similar things.  Because the code needs to be compiled under VC++ 4.1 (to
> >produce the Windows 95/NT version), VC++ 1.5 (to produce the Windows 3.1
> >version) and Watcom C++ to produce an NLM version, these try and catch
> >blocks also have #ifdefs in them and they consume a substantial amount of
> >the source code when added together.

> >Is there a way to associate a single set of try and catch blocks with
> >multiple methods?

> >Thanks.

> >Jerry

-- Aaron [MVP]
---------------------
Aaron J Margosis

ScrnSaveSwitch/Plus - Screen Saver Control Utility:
http://www.ssswitch.com


Mon, 25 Sep 2000 03:00:00 GMT  
 Try catch blocks - can multiple methods share a single try/catch combination?

One more suggestion you may find a bit cleaner and more robust.

// Common exception handler function
void CommonHandler()
{
   try
   {
      throw;   // Re-throw to determine type of exception
   }
   catch ( exception &ex )
   {
      clog << "Caught: " << typeid(ex).name() << endl;
      clog << ex.what() << endl;
      throw;
   }
   catch ( ... )
   {
      clog << "Caught: Unknown exception!" << endl;
      throw;
   }

Quote:
}

// Main
void main()
{
    try
    {
        // Do some work which may throw an exception
        . . .
    }
    catch( ... )
    {
        // Do some clean-up
        . . .
        // Call common exception handler
        CommonHandler();
    }

Quote:
}

This technique makes use of a common exception handling function.  This
function re-throws the exception within it's own try block in order to
determine the type of exception and handle it appropriately.  The function
returns by re-throwing the exception from the catch block, there-by passing
the exception back down the stack.

Steve Clark



Fri, 29 Sep 2000 03:00:00 GMT  
 Try catch blocks - can multiple methods share a single try/catch combination?



Quote:
>This technique makes use of a common exception handling function.  This
>function re-throws the exception within it's own try block in order to
>determine the type of exception and handle it appropriately.  The function
>returns by re-throwing the exception from the catch block, there-by passing
>the exception back down the stack.

Unfortunately, it might be unsafe. If you "throw;" in a try block, VC5
may double-destruct the object caught by reference. Consider:

#include <iostream>
using namespace std;

struct A
{
   A()         { cout << "ctor: " << this << endl; }
   A(const A&) { cout << "copy ctor: " << this << endl; }
   ~A()        { cout << "dtor: " << this << endl; }

Quote:
};

void main()
{
   try
   {
      throw A();
   }
   catch (A&)
   {
      try
      {
         throw;
      }
      catch (A&)
      {
      }
   }

Quote:
}

E>cl -GX k1.cpp
E>k1
ctor: 0012FF6C
dtor: 0012FF6C
dtor: 0012FF6C

I've only seen this problem when using "throw;" in a try block. Other,
more common practices seem to work fine.

--
Doug Harrison



Fri, 29 Sep 2000 03:00:00 GMT  
 Try catch blocks - can multiple methods share a single try/catch combination?

Quote:

>Unfortunately, it might be unsafe. If you "throw;" in a try block, VC5
>may double-destruct the object caught by reference. Consider:

Doug,

I believe my suggestion is valid but, you did catch me in a coding blunder.
You are correct that VC5 will 'double-destruct' an exception if given the
chance.  This behaviour is due to some ambiguity in the C++ Draft Standard
which has been addressed and should be corrected in future VC releases.

My example avoids the 'double-destruct' behaviour by re-throwing the
exception to pass it down the stack.  My mistake was in using the 'main()'
function as an example.  Re-throwing an exception from a catch block in
main() only confuses things by causing an 'uncaught exception' error.

For now, if you want to use a common exception handling function in main(),
you can wrap the code in a 'do nothing' try-catch block.  This is not a
pretty solution but, the situation should be corrected in future VC releases
and the wrapper try-catch block can be removed.  My revised code follows:

// Common exception handler function
void CommonHandler()
{
   try
   {
      throw;   // Re-throw to determine type of exception
   }
   catch ( exception &ex )
   {
      clog << "Caught: " << typeid(ex).name() << endl;
      clog << ex.what() << endl;
      throw;
   }
   catch ( ... )
   {
      clog << "Caught: Unknown exception!" << endl;
      throw;
   }

Quote:
}

// Main
void main()
{
    try
    {
        try
        {
            // Do some work which may throw an exception
            . . .
        }
        catch( ... )
        {
            // Do some clean-up
            . . .
            // Call common exception handler
            CommonHandler();
        }
    }
    catch( ... ) { }
Quote:
}

>#include <iostream>
>using namespace std;

>struct A
>{
>   A()         { cout << "ctor: " << this << endl; }
>   A(const A&) { cout << "copy ctor: " << this << endl; }
>   ~A()        { cout << "dtor: " << this << endl; }
>};

>void main()
>{
>   try
>   {
>      throw A();
>   }
>   catch (A&)
>   {
>      try
>      {
>         throw;
>      }
>      catch (A&)
>      {
>      }
>   }
>}

>E>cl -GX k1.cpp
>E>k1
>ctor: 0012FF6C
>dtor: 0012FF6C
>dtor: 0012FF6C

>I've only seen this problem when using "throw;" in a try block. Other,
>more common practices seem to work fine.

>--
>Doug Harrison




Sat, 30 Sep 2000 03:00:00 GMT  
 Try catch blocks - can multiple methods share a single try/catch combination?



Quote:
>My example avoids the 'double-destruct' behaviour by re-throwing the
>exception to pass it down the stack.

That seems to be the key. In the catch block, if you don't rethrow it,
or you throw a different exception, VC5 double-destructs the original
object. Again, I've only observed this when using "throw;" in a try
block, so I'd still recommend being very careful with that technique.

--
Doug Harrison



Sat, 30 Sep 2000 03:00:00 GMT  
 
 [ 7 post ] 

 Relevant Pages 

1. Try catch blocks - can multiple methods share a single try/catch combination?

2. TRY-CATCH vs. try-catch

3. try/catch VS TRY/CATCH

4. The if ~ else block in try~catch block

5. Can you catch CDBExection with try-catch keyword?

6. why {try catch} does not catch

7. Q: Why try catch cannot catch the exception

8. Optimizer ignores try-catch block

9. try catch block

10. does atl support try..catch block?(empty inside)

11. Overhead of try-catch blocks?

12. /Og causes intermittent omission of try..catch block

 

 
Powered by phpBB® Forum Software