Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Void

Mental block with exceptions

This topic is 7119 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
Advertisement
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

Share this post


Link to post
Share on other sites
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++..

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
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.

Share this post


Link to post
Share on other sites
really??.. I thought it was more of a limitation from the win32 C days..

Share this post


Link to post
Share on other sites
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
}

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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..

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!