C++ exceptions can't cross COM module boundaries.
So, assume we are in a COM method body, and some C++ potentially-throwing method/function is called (this can throw because e.g. STL classes are used):
STDMETHODIMP CSomeComServer::DoSomething()
{
CppDoSomething(); // <--- This may throw C++ exceptions
return S_OK;
}
Q1. Is the above code a viable implementation?
For example, if that code is part of a context menu shell extension, if the C++ CppDoSomething() function throws a C++ exception, what does Explorer do? Does it catch the C++ exception and unload the shell extension? Does it just crash Explorer (making it possible to analyze the problem using a crash dump) following a fail-fast approach?
Q2. Would an implementation like this be better?
STDMETHODIMP CSomeComServer::DoSomething()
{
//
// Wrap the potentially-throwing C++ code call in a safe try/catch block.
// C++ exceptions are caught and transformed to HRESULTs.
//
try
{
CppDoSomething(); // <--- This may throw C++ exceptions
return S_OK;
}
//
// Map C++ std::bad_alloc exception to E_OUTOFMEMORY HRESULT.
//
catch(const std::bad_alloc& ex)
{
// ... Log the exception what() message somewhere,
// e.g. using OutputDebugString().
....
return E_OUTOFMEMORY;
}
//
// Map C++ std::exception exception to generic E_FAIL.
//
catch(const std::exception& ex)
{
// ... Log the exception what() message somewhere,
// e.g. using OutputDebugString().
....
return E_FAIL;
}
}
Q3. Or would it be even better, if a C++ exception is thrown, to just set an internal flag (e.g. a bool m_invalid data member) to put the COM server in a state such that it can't work anymore, so every successive call to its method returns some error code, like E_FAIL or some other specific error?
Q4. Finally, assuming that Q2/Q3 are good implementation guidelines, it's possible to hide the verbose try/catch guard in some convenient preprocessor macros (that can be reused in every COM method body), e.g.
#define COM_EXCEPTION_GUARD_BEGIN try \
{
#define COM_EXCEPTION_GUARD_END return S_OK; \
} \
catch(const std::bad_alloc& ex) \
{ \
.... \
return E_OUTOFMEMORY; \
} \
catch(const std::exception& ex) \
{ \
.... \
return E_FAIL; \
}
//
// May also add other mappings, like std::invalid_argument --> E_INVALIDARG ...
//
STDMETHODIMP CSomeComServer::DoSomething()
{
COM_EXCEPTION_GUARD_BEGIN
CppDoSomething(); // <--- This may throw C++ exceptions
COM_EXCEPTION_GUARD_END
}
STDMETHODIMP CSomeComServer::DoSomethingElse()
{
COM_EXCEPTION_GUARD_BEGIN
CppDoSomethingElse(); // <--- This may throw C++ exceptions
COM_EXCEPTION_GUARD_END
}
Using modern C++11/14, is it possible to replace the aforementioned preprocessor macros with something else, more convenient, more elegant, just better?
Never let exceptions propagate across COM boundary, otherwise the behavior is undefined and may include your C++ runtime terminate() being called, the process going nuts and other nice bonuses. Just don't do it. Even if you "tested" it in some configuration - it's still undefined behavior and will silently break should minor environment or implementation changes occur.
You should catch and translate all C++ exceptions into HRESULTs and optionally set IErrorInfo with details. You can do so with macros wrapping each COM server method implementation or by copy-pasting this code everywhere - guess which is more maintainable.
The idea with driving the server into "invalid" state may make sense in some extreme situations but I can't imagine them at the moment. I guess it's not a universal solution. In general cases if you have exception safe code you shouldn't need this at all.
Related
I have searched a lot for the differences between these two types of handlers, but everyone said that catch(...) is a generic handler which catches everything.
I could not find any exception that one of them can handle and the other cannot. Even divide by zero, creates an exception that both of them cannot handle (floating point exception).
Can anyone give me a sample and explain clearly their difference? Which one of them should I use?
Is there any exception that catch(...) can handle while catch(exception& ex) cannot?
Yes, any exception that is not, or not derived from, std::exception will not be caught by catch(exception&). For example; throw 42; will be caught by catch(...), but not catch(exception&).
A throw exception(); can be caught by either; the first handler is chosen. The catch(...) should be the last handler.
Even divide by zero, creates an exception which both of them cannot handle (floating point exception)...
Visual Studio has two modes of exception handling; synchronous (/EHsc) and asynchronous (/EHa). For the synchronous handling, both catch(...) and catch(exception&) will only catch C++ exceptions; i.e. those thrown with a throw xyz;. For the asynchronous handling, access violations etc. can be caught with catch(...).
VS also offers a function _set_se_translator() that can be used to "translate" or handle the Win32 exceptions. Typically the function is used to translate the Win32 exception to a C++ exception (derived from exception) that can be handled by a catch(exception&).
A sample of what the translation could look like (some detail is omitted for brevity);
struct seh_exception : std::runtime_error {
//...
};
struct access_violation : seh_exception {
//...
};
struct unspecified_seh_exception : seh_exception {
//...
};
void translation_function(unsigned int code, ::EXCEPTION_POINTERS* info)
{
switch (code) {
case EXCEPTION_ACCESS_VIOLATION:
throw access_violation();
break;
// more cases for other exception codes
};
throw unspecified_seh_exception();
}
Which one of them should I use?
You should use the one that you can do something with. If all exceptions result in the same handling by your code, then use catch(...). If your code needs to handle the exceptions separately, then you should have a handler for each exception that is expected.
Sure, any exception that is of a type that doesn't have std::exception as its base class will not be caught by catch(std::exception& ex).
For example,
struct foo {};
throw foo();
will be caught by catch (...), and not by std::exception.
You are allowed to throw pretty much anything (e.g an int), and catch(...) will catch anything. catch(exception&) will only catch exception or derived types.
catch(...){} is catching all exceptions. catch(std::exception& ex){} is catching all exceptions with std::exception as a base class.
http://en.cppreference.com/w/cpp/language/try_catch
In my project codding i have to use a try catch method to find the function execution status.
try
{
//sample code
//calling functions
function1();
function2();
//........
}
catch(//need to catch exception)
{
return failure;
}
My requirement is that i have to catch all the exceptions that thrown from the try block
i have two options here,
catch(...)
catch(std::exception)
I think the first one will catch all the exceptions. And the second one, std::exception is the base class for all other exception classes in my program
class MyException : public std::exception
{
// All the exceptions that i have use is derived from this class
}.
Which is better and more efficient.
Is the both method works same way. Help me and suggest any method
In this case, you'd work your way through the types which may be thrown in the following order:
catch (MyException& e) {
...
}
catch (std::exception& e) {
...
}
catch (...) {
...
}
This way, you can handle the specific errors/types first, and then fall back on the weak (or untyped) handlers when the preceding handlers do not match.
Which is better and more efficient.
The order I recommended is best for handling by type. IMO, efficiency is not a concern in this scenario because correctness takes precedence and hopefully exceptions are thrown only under exceptional circumstances.
Always keep your specification as focused as possible so that you catch those that you know could be thrown, and catch derived exceptions (more specialised) before base ones:
try
{
// Some stuff
}
catch (Derived& e)
{
// Deal with specifics of Derived
}
catch (Base& e)
{
// Deal with general case of Base
}
Never use catch(...) except at the very top of your program stack (and certainly not in libraries.) When you do this, you cannot be sure about what caused the exception and therefore you cannot necessarily rely on things that you normaly would (such as memory management etc.)
I would suggest you to catch the specified exceptions only and use the catch(...) only in the main function. In my opinion the better way to use the exceptions is to implement one exception per module so each class will throw the specific exception related with the module of the class also different exceptions may be handled with a different way so I believe that
catch(const ExceptionType1& e){
}catch(const ExceptionType2& e){
}
is the better solution, also some other developer just reading this code will see which kind of exceptions could be thrown and handled....
I am writing a library in C++ which uses an older C API. The client of my library can specify callback functions, which are indirectly called through my library which is called through the C API. This means that all exceptions in the client callbacks must be handled.
My question is this: how can I catch the exception on one side of the boundary and re-throw it once the C API boundary has been recrossed and the execution is back in C++ land so that the exception can be handled by client code?
With C++11 we could use:
std::exception_ptr active_exception;
try
{
// call code which may throw exceptions
}
catch (...)
{
// an exception is thrown. save it for future re-throwing.
active_exception = std::current_exception();
}
// call C code
...
// back to C++, re-throw the exception if needed.
if (active_exception)
std::rethrow_exception(active_exception);
Before C++11 these can still be used via Boost Exception.
Some environments support this more or less directly.
For instance, if you enable structured exception handling and C++ exceptions through the /EH compiler switch, you can have C++ exceptions implemented over Microsoft's structured exception handling ("exceptions" for C). Provided these options are set when compiling all your code (the C++ at each end and the C in the middle) stack unwinding will "work".
However, this is almost always a Bad Idea (TM). Why, you ask? Consider that the piece of C code in the middle is:
WaitForSingleObject(mutex, ...);
invoke_cxx_callback(...);
ReleaseMutex(mutex);
And that the invoke_cxx_callback() (....drum roll...) invokes your C++ code that throws an exception. You will leak a mutex lock. Ouch.
You see, the thing is that most C code is not written to handle C++-style stack unwinding at any moment in a function's execution. Moreover, it lacks destructors, so it doesn't have RAII to protect itself from exceptions.
Kenny TM has a solution for C++11 and Boost-based projects. xxbbcc has a more general, albeit more tedious solution for the general case.
You can probably pass a structure across the C interface that gets filled out with error information in case of an exception and then when that is received on the client side, check it and throw an exception inside the client, based on data from the structure. If you only need minimal information to recreate your exception, you can probably just use a 32-bit/64-bit integer as an error code. For example:
typedef int ErrorCode;
...
void CMyCaller::CallsClient ()
{
CheckResult ( CFunction ( ... ) );
}
void CheckResult ( ErrorCode nResult )
{
// If you have more information (for example in a structure) then you can
// use that to decide what kind of exception to throw.)
if ( nResult < 0 )
throw ( nResult );
}
...
// Client component's C interface
ErrorCode CFunction ( ... )
{
ErrorCode nResult = 0;
try
{
...
}
catch ( CSomeException oX )
{
nResult = -100;
}
catch ( ... )
{
nResult = -1;
}
return ( nResult );
}
If you need more information than a single int32/int64 then you can allocate a structure before the call and pass its address to the C function which will, in turn, catch exceptions internally and if they happen, throws an exception on its own side.
Here's the setup.
I have a C++ program which calls several functions, all of which potentially throw the same exception set, and I want the same behaviour for the exceptions in each function
(e.g. print error message & reset all the data to the default for exceptionA; simply print for exceptionB; shut-down cleanly for all other exceptions).
It seems like I should be able to set the catch behaviour to call a private function which simply rethrows the error, and performs the catches, like so:
void aFunction()
{
try{ /* do some stuff that might throw */ }
catch(...){handle();}
}
void bFunction()
{
try{ /* do some stuff that might throw */ }
catch(...){handle();}
}
void handle()
{
try{throw;}
catch(anException)
{
// common code for both aFunction and bFunction
// involving the exception they threw
}
catch(anotherException)
{
// common code for both aFunction and bFunction
// involving the exception they threw
}
catch(...)
{
// common code for both aFunction and bFunction
// involving the exception they threw
}
}
Now, what happens if "handle" is called outside of the exception class.
I'm aware that this should never happen, but I'm wondering if the behaviour is undefined by the C++ standard.
If handle() is called outside the context of an exception, you will throw without an exception being handled. In this case, the standard (see section 15.5.1) specifies that
If no exception is presently being handled, executing a throw-expression with no operand calls terminate().
so your application will terminate. That's probably not what you want here.
If you use throw inside of a catch block, it will rethrow the exception. If you use throw outside of a catch block, it will terminate the application.
Never, never, never use catch(...) as you might catch application errors that you don't want to catch, e.g. bugs, access violations (depending on how you compiled).
Read the great John Robbins book (Debugging Windows Applications) in which he explains more in detail why you shouldn't do it.
In C++, I'm trying to catch all types of exceptions in one catch (like catch(Exception) in C#). How is it done? And what's more, how can one catch divide-by-zero exceptions?
catch (...)
{
// Handle exceptions not covered.
}
Important considerations:
A better approach is to catch specific types of exception that you can actually recover from as opposed to all possible exceptions.
catch(...) will also catch certain serious system level exceptions (varies depending on compiler) that you are not going to be able to recover reliably from. Catching them in this way and then swallowing them and continuing could cause further serious problems in your program.
Depending on your context it can be acceptable to use catch(...), providing the exception is re-thrown. In this case, you log all useful local state information and then re-throw the exception to allow it to propagate up. However you should read up on the RAII pattern if you choose this route.
You don't want to be using catch (...) (i.e. catch with the ellipsis) unless you really, definitely, most provable have a need for it.
The reason for this is that some compilers (Visual C++ 6 to name the most common) also turn errors like segmentation faults and other really bad conditions into exceptions that you can gladly handle using catch (...). This is very bad, because you don't see the crashes anymore.
And technically, yes, you can also catch division by zero (you'll have to "StackOverflow" for that), but you really should be avoiding making such divisions in the first place.
Instead, do the following:
If you actually know what kind of exception(s) to expect, catch those types and no more, and
If you need to throw exceptions yourself, and need to catch all the exceptions you will throw, make these exceptions derive from std::exception (as Adam Pierce suggested) and catch that.
If you are on windows and need to handle errors like divide by zero and access violation you can use a structured exception translator. And then inside of your translator you can throw a c++ exception:
void myTranslator(unsigned code, EXCEPTION_POINTERS*)
{
throw std::exception(<appropriate string here>);
}
_set_se_translator(myTranslator);
Note, the code will tell you what the error was. Also you need to compile with the /EHa option (C/C++ -> Code Generatrion -> Enable C/C++ Exceptions = Yes with SEH Exceptions).
If that doesn't make sense checkout the docs for [_set_se_translator](http://msdn.microsoft.com/en-us/library/5z4bw5h5(VS.80).aspx)
If catching all exceptions - including OS ones - is really what you need, you need to take a look at your compiler and OS. For example, on Windows you probably have "__try" keyword or compiler switch to make "try/catch" catch SEH exceptions, or both.
Make all your custom exception classes inherit from std::exception, then you can simply catch std::exception. Here is some example code:
class WidgetError
: public std::exception
{
public:
WidgetError()
{ }
virtual ~WidgetError() throw()
{ }
virtual const char *what() const throw()
{
return "You got you a widget error!";
}
};
In C++, the standard does not define a divide-by-zero exception, and implementations tend to not throw them.
You can, of course, use catch (...) { /* code here */ }, but it really Depends On What You Want To Do. In C++ you have deterministic destructors (none of that finalisation rubbish), so if you want to mop up, the correct thing to do is to use RAII.
For example. instead of:
void myfunc()
{
void* h = get_handle_that_must_be_released();
try { random_func(h); }
catch (...) { release_object(h); throw; }
release_object(h);
}
Do something like:
#include<boost/shared_ptr.hpp>
void my_func()
{
boost::shared_ptr<void> h(get_handle_that_must_be_released(), release_object);
random_func(h.get());
}
Create your own class with a destructor if you don't use boost.
You can use catch(...) to catch EVERYTHING, but then you don't get a an object to inspect, rethrow, log, or do anything with exactly. So... you can "double up" the try block and rethrow into one outer catch that handles a single type. This works ideally if you define constructors for a custom exception type that can build itself from all the kinds you want to group together. You can then throw a default constructed one from the catch(...), which might have a message or code in it like "UNKNOWN", or however you want to track such things.
Example:
try
{
try
{
// do something that can produce various exception types
}
catch( const CustomExceptionA &e ){ throw e; } \
catch( const CustomExceptionB &e ){ throw CustomExceptionA( e ); } \
catch( const std::exception &e ) { throw CustomExceptionA( e ); } \
catch( ... ) { throw CustomExceptionA(); } \
}
catch( const CustomExceptionA &e )
{
// Handle any exception as CustomExceptionA
}
If I recall correctly (it's been a while since I've looked at C++), I think the following should do the trick
try
{
// some code
}
catch(...)
{
// catch anything
}
and a quick google(http://www.oreillynet.com/pub/a/network/2003/05/05/cpluspocketref.html) seems to prove me correct.