Mental block with exceptions

Started by
14 comments, last by Void 23 years, 11 months ago
I have this confusion about SEH and exceptions, which I hope somebody can answer me.. I use a mixture of C and C++ style coding.. C for win32 calls, classes for others.. My problem: try, throw, catch in C++ are better suited for objects as during unwinding, the destructors are called automatically. However, the try, catch doesn''t work nicely with functions that doesn''t use classes, like in most win32 calls So if I have to manually deallocate resource, it means the deallocation routines have to be duplicated for each catch statement and the end of the function, like so void Function() { try { // allocate resource } catch(Exception e) // some specific Exception { // deallocate resource - duplicated } catch (...) // generic Exception { // deallocate resource - duplicated } // deallocate resource - when function succeeds } Is that the correct and only way of using exceptions in this situation? Is there a way to place all the deallocation routines in one block, much like SEH (Structured Exception handling) __finally, or even Java, where finally keyword is available? Note: SEH does not allow objects inside their try/catch that have destructors so it cannot be used with classes.
Advertisement
hmm.. no one knows??..
Try this:


void Function()
{
try
{
// allocate resource

// deallocate resource - when function succeeds (#1)
}

catch(Exception e) // some specific Exception
{
// handle exception

throw; // now caught by catch(...) for deallocation
}
catch (...) // generic Exception
{
// deallocate resource (#2)

throw; // throw it up to the function caller
}
}



Make sure that code works (with a console app?) before using it extensively.

A really good way to avoid duplicating cleanup code is to use objects on the stack that deallocate their own memory, so as their destructors go out of scope, the memory is deallocated. There is almost always a way of wrapping heap memory with a stack object.

You could try auto_ptr, but it does use delete and not delete[] so it won''t handle arrays properly.



- null_pointer
Sabre Multimedia
Thanks..

but notice you still have to have two deallocation routines, which is not as "clean" as the __finally keyword (which is executed regardless an exception is thrown or not)

It is not possible(??) to make a stack based allocation when it comes to win32 calls like GetDC()/ ReleaseDC()..

Oh well, it seems like a design flaw in C++..
You can''t have objects with destructors inside SEH code. That''s one of the reasons why SEH is more efficient than C++ or MFC exception handling.
really??.. I thought it was more of a limitation from the win32 C days..
null_pointer was incorrect in his first post. using throw will NOT cause another exception handler in the same block to catch the exception ... it will throw the exception OUT of the block, to be caught at the end of an external try/catch set. see below for details

try // 1
{
try // 2
{
//error here ... throws ExpClassA
}
catch(ExpClassA e)
{
//error first caught here
throw;
}
catch(...)
{
// nothing caught here ... never called
}
}
catch(...)
{
// rethrown error caught here
}
Void, try this -- a very simple encapsulation of GetDC/ReleaseDC.

class DC{public:  DC (HWND hwnd) : _hwnd(hwnd), _hdc(::GetDC (hwnd)) {}  ~DC ()  {    ::ReleaseDC (_hwnd, _hdc);  }  operator HDC () { return _hdc };protected:  HDC   _hdc;  HWND  _hwnd;};// somewhere in the program body....try{  ...  DC dc(hwnd);  // some throw happen...  // but no worries, the DC class release itself.}catch (...){  // blah blah...}


There''s still many ways. Happy coding.

"after many years of singularity, i'm still searching on the event horizon"
Oh yes, Sai, you are correct there..

Derek, thanks.. the GetDC/ReleaseDC was only a simple call that is frequently used.. but wait.., you mean I have to write a class for each type of heap allocation I make?? Sounds like a lot of work to me..
Most probably yes. But I could count them with my hand, there's not much after all. Most are Lock/Unlock, GetDC/ReleaseDC (Windows & DirectX), Open/Close (usually files).

If you want to grow beautiful flowers, you need to get your hand dirty.

BTW, I never used __finally . Is it a standard or MS Specific? And where could I read something about SEH?


Edited by - DerekSaw on May 16, 2000 12:16:55 AM
"after many years of singularity, i'm still searching on the event horizon"

This topic is closed to new replies.

Advertisement