When I’m programming C code for Windows, should I “default” to using SEH’s __try…__finally blocks, or is it considered bad practice to do so unnecessarily?
In other words, which one below (for example) is considered better practice, and why?
HDC hDCCompat = CreateCompatibleDC(hDC);
__try
{
HBITMAP hBmpCompat = CreateCompatibleBitmap(hDC, ...);
__try
{
SelectObject(hDCCompat, hBmpCompat);
BitBlt(hDC, ..., hDCCompat, ...);
}
__finally { DeleteObject(hBmpCompat); }
}
__finally { DeleteObject(hDCCompat); }
versus
HDC hDCCompat = CreateCompatibleDC(hDC);
HBITMAP hBmpCompat = CreateCompatibleBitmap(hDC, ...);
SelectObject(hDCCompat, hBmpCompat);
BitBlt(hDC, ..., hDCCompat, ...);
DeleteObject(hBmpCompat);
DeleteObject(hDCCompat);
Clarification
I forgot to mention:
My idea behind this was that, if someone inserts more code later into the block (e.g. an early return from the function), my code would still perform the cleanup, rather than exiting prematurely. So it was supposed to be more preventive than anything else. Should I still avoid using SEH anyway?
In my opinion, no. The downside is a lot of extra
__try/__finallynoise and I don’t see what the upside is.How are you expecting these to fail? For example
SelectObjectreports an error by returningNULL(which you don’t check for), not by raising an SEH exception. Many instances of SEH exceptions indicate a fundamental error that isn’t recoverable (you have corrupted memory or you’ve made a logic error such as passing in an invalid handle to a function or something). These sorts of errors can’t be handled gracefully and a crash is typically easier to debug.If you want to make your code robust in the face of early returns (which many C coding standards discourage, in part for this reason) then you should consider structuring your code in a way where it is more difficult to modify in dangerous ways. E.g.
You can hope that because this function is simple there will be little temptation to put in additional early returns, early returns in the called “logic” function don’t harm the clean-up of the acquired resource.