How to Throw a C++ Exception

What are exceptions and why throw them?

Something to keep in mind is not only that caught exceptions can be used for logging errors, they can be used for handling errors that might arise.

Let's say you have some kind of Widget object, that has properties you initialize via arguments to a constructor:

public class Widget
{
public string Name;

Widget(string widgetName)
{
if (widgetName != "")
Name = widgetName;
else
throw new ArgumentException("Name must be provided for widget.");
}
}

In this case, we have a situation where we want to require our Widget have a name when it's instantiated - we check the argument to see if it's blank, and we throw an ArgumentException to indicate that something is wrong with one of the arguments to the constructor, as well as include a helpful message about what specifically went wrong.

This means we can then have context-specific validation logic in a wrapper, rather than having to have everything crammed into our base Widget class:

public Widget ForCaseA (string widgetName) 
{
Widget w;

try {
w = new Widget(widgetname);
}

catch (ArgumentException as argEx) // We're specifically catching the subtype of ArgumentExceptions; generic Exceptions or other types of exception wouldn't be caught here and would bubble up out of this try/catch block.
{
// At this point, we could look at the specific data in the exception object to determine what needs to happen to resolve the exception. Since there's only one argument and it's throwing an ArgumentException, we know it's going to be a problem with a bad widgetName. In this case, we can say 'well, in this specific case, we want to give it a default widget name'.
w = new Widget("DefaultName");
}

return w;
}

One of the ways catching exceptions by type becomes exceptionally useful is when you use inheritance to create your own types based off the generic Exception class; e.g. giving your Widgets a WidgetException. This lets you catch issues specific to your class/entity (like the widget's name), but doesn't have to handle issues that fall outside the scope of the Widget itself.

How to throw a C++ exception

Simple:

#include <stdexcept>

int compare( int a, int b ) {
if ( a < 0 || b < 0 ) {
throw std::invalid_argument( "received negative value" );
}
}

The Standard Library comes with a nice collection of built-in exception objects you can throw. Keep in mind that you should always throw by value and catch by reference:

try {
compare( -1, 3 );
}
catch( const std::invalid_argument& e ) {
// do stuff with exception...
}

You can have multiple catch() statements after each try, so you can handle different exception types separately if you want.

You can also re-throw exceptions:

catch( const std::invalid_argument& e ) {
// do something

// let someone higher up the call stack handle it if they want
throw;
}

And to catch exceptions regardless of type:

catch( ... ) { };

Throw a C# exception of the same type as that caught?

Creating a new exception type isn't a good option for a general method like this, since existing code will be unable to react to a specific error. (Translation exceptions at API boundaries cane be useful, though).

Creating a new exception of the same type seems perilous. Does the CreateInstance overload you're using copy all fields from the innerException to your new outer exception? What if an exception handler higher up the stack depends on parsing the Message property? What if the exception constructor has side effects?

IMHO, what you're really doing is logging, and you'd probably be better off actually doing logging and a re-throw.

How to know if some method can throw an exception

You will have to consult the documentation for that. C# lacks a throws keyword.

The term for what you are looking for is checked exceptions, and more info can be found in the C# FAQ.

Throwing C++ exception through C function call

This is platform-specific and compiler-specific question.

For example, on Linux/GCC, you have to compile C code with -fexceptions option, then unwind tables would be build and exception will go throw C code.

From https://gcc.gnu.org/onlinedocs/gcc-7.3.0/gcc/Code-Gen-Options.html#index-fexceptions

-fexceptions

Enable exception handling. Generates extra code needed to propagate
exceptions. For some targets, this implies GCC generates frame unwind
information for all functions, which can produce significant data size
overhead, although it does not affect execution. If you do not specify
this option, GCC enables it by default for languages like C++ that
normally require exception handling, and disables it for languages
like C that do not normally require it. However, you may need to
enable this option when compiling C code that needs to interoperate
properly with exception handlers written in C++. You may also wish to
disable this option if you are compiling older C++ programs that don’t
use exception handling.

I'm less familiar with Visual C++/Windows development, but I believe exceptions handling will use common mechanisms if you compile your C++ and C code with /EHa option (allow mix of structured and C++ exceptions)

C#: Do you raise or throw an exception?

In C# terminology, raising is used in the context of events and throwing is used in the context of exceptions.

Personally, I think throw/catch combination is more beautiful than raise/catch.



Related Topics



Leave a reply



Submit