views:

245

answers:

5

Hi,

I'm wondering which is the better way to catch exceptions that I throw: is it a __try / __except block or a try / catch block?

I'm writing in C++ and the program will only be used on Windows, so portability is not an issue.

Thanks!

+11  A: 

They are two very different things. try/catch are the familiar C++ keywords you know. __try/__except is used to catch SEH exceptions. Exceptions raised by Windows itself, like DivisionByZero or AccessViolation. It is well described in the MSDN Library article for it.

You can also use it to catch C++ exception because it leverages the Windows SEH feature. You however can't get the thrown exception object out of it so there will be zero context if you actually want the handle the exception. Which is madness. The number one approach is to not ever catch SEH exceptions, they are always gross. If you do need to marry the two then use _set_se_translator() to convert the SEH exception to a C++ exception.

Hans Passant
+1 for MSDN ref.
Billy ONeal
+3  A: 

__try/__except is designed for calling Win32 C code which doesn't support exceptions but does use a structured error code / handling mechanism. __try/__except will translate C errors into an exception block similar to C++ try/catch.

For more information, see this MSDN article.

Randolpho
+1 for MSDN ref
Billy ONeal
+1  A: 

Standard C++ uses try/catch blocks, so I would recommend using them, if you need the "standard" exception mechanism, based on standard C++ library.

However, if you plan to use Structured Exception Handling provided through Windows SDK (see here), then use __try/__except.

Cătălin Pitiș
-1: The STL has absolutely nothing to do with exception handling.
Billy ONeal
The STL has absolutely something to do with exception handling: std::exception, which is the recommended base class for exceptions, even if it is not mandatory.
Cătălin Pitiș
`std::exception` is not an STL class.
Billy ONeal
Sorry. Standard C++ Library is better phrased?
Cătălin Pitiș
@Cătălin Pitiș: Yes, that would be better, but still wouldn't be *quite* pedantic :) (I would remove my downvote after an edit to that effect)
Billy ONeal
@Cătălin Pitiș: Downvote removed.
Billy ONeal
+2  A: 

You should use a try/catch block.

As others have already answered, __try / __except is for catching SEH (windows generated errors) not for catching general exceptions.

Most importantly, __try and __catch does not run C++ destructors or correctly unwind the stack when an exception is thrown.

Except in rare cases, you should never try to catch SEH exceptions.

EDIT: Well, I was positive on this (it's what I've always been told), but @Hans says that apparently there is a compiler switch you can use to change this. I think the docs on /EHa are misleading, or at least incomplete, on what happens here. If someone finds definitive docs which prove this wrong, I'll happily remove this answer.

Even if it turns out this is false, you should still use try and catch simply because they are standard, while __try and __except are not.

Billy ONeal
So it doesn't unwind the stack? That means that it's probably a really bad idea to use `__try`/`__except` as anything other than a crash reporting system, whereas it's common to be able to recover from an exception in a `try`/`catch` block.
David Thornley
@David: That is correct. `__try` and `__except` are strictly a C based API/ABI.
Billy ONeal
The only good uses for it I've seen have been dealing with what amounted to bugs in Windows itself (such as what used to happen when you tried to copy a device). Arguably they're always indicative of somewhere where Windows should have caught the exception for you and translated it into an error. (The way they work is horrific too, and very very x86-specific…)
Donal Fellows
That's not accurate. Compiling with /EHa guarantees C++ destructor calls during stack unwinding.
Hans Passant
@Hans: Can you find documentation to that effect? My understanding of `/EHa` is merely that it allows C++ exception handling constructs (when you use `try` and `catch`) to catch SEH exceptions, but that the C++ stack is still not correctly unwound when `__try` and `__except` are used.
Billy ONeal
The /EH documentation is all there is. Yes, it isn't great. /EHa suppresses a compiler optimization that omits exception cleanup handlers when the compiler detects that none of the emitted code can throw a C++ exception. You can see them when you look at the machine code.
Hans Passant
+1  A: 

Once you've thrown something, you no longer have much choice about how to catch it. If you throw C++ exceptions (i.e., with throw), then use try/catch. If you throw Windows exceptions (i.e., with RaiseException), then use __try/__except. Trying to mix them will just be adding unnecessary hassle to your life.

Rob Kennedy
But you should never thrown windows exceptions because they do not unwind the stack.
Billy ONeal